import { agent_dispatch_tool_call } from "std/agent/primitives"
import { agent_tool_handler_result } from "std/agent/tool_lifecycle"
fn __composition_registry(harness: Harness, value: any) {
if value == nil {
const current = harness.tools.current_registry()
if current == nil {
return tool_registry()
}
return __composition_registry(harness, current)
}
if type_of(value) == "dict" && type_of(value?.tools) == "list" {
return value
}
if type_of(value) == "list" {
return {_type: "tool_registry", tools: value}
}
throw "composition_mcp: tools must be a tool registry, list, or nil"
}
fn __composition_mcp_tool(entry: dict) {
if type_of(entry) != "dict" {
return false
}
if entry?.executor == "mcp_server" || entry?._mcp_server != nil || entry?.mcp_server != nil
|| entry?._mcp_tool_name
!= nil {
return true
}
const function = entry?.function
if type_of(function) == "dict" {
return function?.executor == "mcp_server" || function?._mcp_server != nil
|| function?.mcp_server
!= nil
|| function?._mcp_tool_name != nil
}
return false
}
fn __composition_mcp_registry(harness: Harness, value: dict) {
const registry = __composition_registry(harness, value)
let tools = []
for entry in registry?.tools ?? [] {
if __composition_mcp_tool(entry) {
tools.push(entry)
}
}
return registry + {tools: tools}
}
fn __composition_mcp_ranked_names(registry: any, query: string?, options: dict?) {
const text = trim(to_string(query ?? ""))
if text == "" {
return nil
}
const opts = options ?? {}
const ranked = __host_tool_search_score(
text,
registry,
{strategy: opts?.strategy ?? "bm25", max_results: opts?.limit ?? opts?.max_results ?? 20},
)
let names = []
for item in ranked {
if item?.tool_name != nil {
names.push(item.tool_name)
}
}
return names
}
fn __composition_mcp_servers(manifest: dict) {
let servers = []
for binding in manifest?.bindings ?? [] {
const metadata = binding?.metadata ?? {}
const server = metadata?._mcp_server ?? metadata?.mcp_server
if server != nil && !contains(servers, server) {
servers.push(server)
}
}
return servers
}
fn __composition_execute_options(opts: any, dispatcher: any) {
let out = {dispatcher: dispatcher}
for key in [
"session_id",
"run_id",
"max_operations",
"timeout_ms",
"max_output_bytes",
"max_concurrent_operations",
"max_concurrent",
"max_concurrent_per_server",
"per_server_concurrency",
"trusted_servers",
"trusted_mcp_servers",
"trust_annotations",
"trust_mcp_annotations",
"call_timeout_ms",
"retry",
] {
if opts?.[key] != nil {
out = out + {[key]: opts[key]}
}
}
return out
}
fn __composition_dispatch_value(result: dict, name: string) {
if result?.ok ?? false {
return result?.result
}
throw {
schema: "harn.composition.dispatch_error.v1",
message: result?.error ?? result?.rendered_result
?? "composition_mcp_execute: tool failed: ${name}",
error_category: result?.error_category ?? "tool_error",
}
}
fn __composition_mcp_reduced_result(report: dict, opts: dict) {
if opts?.include_report ?? false {
return report
}
const run = report?.run ?? {}
return {
ok: report?.ok ?? false,
result: run?.result,
error: run?.error,
failure_category: run?.failure_category,
run_id: run?.run_id,
child_call_count: len(report?.child_calls ?? []),
}
}
/** Select bindings without accepting caller-supplied policy or dispatch metadata. */
fn __composition_profile_selection(manifest: dict, args: dict) -> dict {
if args?.tools != nil {
return {ok: false, error: "composition_mcp: tools are configured by the server"}
}
if args?.trusted_servers != nil || args?.trusted_mcp_servers != nil
|| args?.trust_annotations != nil
|| args?.trust_mcp_annotations != nil {
return {ok: false, error: "composition_mcp: trust is configured by the server"}
}
const requested = args?.manifest
if requested == nil {
return {ok: true, manifest: manifest}
}
if type_of(requested) != "dict" || type_of(requested?.bindings) != "list" {
return {ok: false, error: "composition_mcp: manifest must contain a list of bindings"}
}
let available_by_binding = {}
for available in manifest.bindings {
available_by_binding[available.binding] = available
}
let seen = {}
let selected = []
for binding in requested.bindings {
const binding_name = binding?.binding
if type_of(binding_name) != "string" {
return {ok: false, error: "composition_mcp: manifest contains an unregistered binding"}
}
const found = available_by_binding[binding_name]
if found == nil || found.name != binding?.name {
return {ok: false, error: "composition_mcp: manifest contains an unregistered binding"}
}
if seen[binding_name] != true {
selected.push(found)
seen[binding_name] = true
}
}
return {ok: true, manifest: manifest + {bindings: selected}}
}
/**
* composition_mcp_manifest builds a Code Mode binding manifest from only MCP-served tools.
*
* @effects: []
* @errors: []
* @api_stability: experimental
*/
pub fn composition_mcp_manifest(harness: Harness, tools: any = nil, options: dict? = nil) {
const opts = options ?? {}
const registry = __composition_mcp_registry(harness, tools)
return composition_binding_manifest(registry, opts?.manifest_options ?? opts)
}
/**
* composition_mcp_api returns the manifest plus prompt-visible Harn API for MCP Code Mode.
*
* @effects: []
* @errors: []
* @api_stability: experimental
* @example: composition_mcp_api(tool_registry, {query: "issues"})
*/
pub fn composition_mcp_api(harness: Harness, tools: any = nil, options: dict? = nil) {
const opts = options ?? {}
const registry = __composition_mcp_registry(harness, tools)
const names = __composition_mcp_ranked_names(registry, opts?.query, opts)
const selected = if names == nil {
registry
} else {
tool_select(registry, names)
}
const manifest = composition_binding_manifest(selected, opts?.manifest_options ?? opts)
return {
manifest: manifest,
harn_api: composition_harn_api(manifest),
tool_count: len(manifest.bindings),
servers: __composition_mcp_servers(manifest),
}
}
/**
* composition_mcp_search searches MCP tools with the same scorer as tool_search and returns a Code Mode API slice.
*
* @effects: []
* @errors: []
* @api_stability: experimental
* @example: composition_mcp_search(tool_registry, "issues", {limit: 5})
*/
pub fn composition_mcp_search(
harness: Harness,
tools: any = nil,
query: string = "",
options: dict? = nil,
) {
const opts = options ?? {}
return composition_mcp_api(harness, tools, opts + {query: query})
}
/**
* composition_mcp_execute runs a Harn Code Mode snippet and dispatches child calls through the agent tool path.
*
* @effects: [host, mcp]
* @errors: []
* @api_stability: experimental
* @example: composition_mcp_execute(harness, "return github_search({query: \"bug\"})", tools)
*/
pub fn composition_mcp_execute(
harness: Harness,
snippet: string,
tools: any = nil,
options: dict? = nil,
) {
const opts = options ?? {}
const source_tools = opts?.tools ?? tools
const registry = __composition_mcp_registry(harness, source_tools)
const manifest = opts?.manifest
?? composition_binding_manifest(registry, opts?.manifest_options ?? opts)
const dispatch_opts = opts?.dispatch_options ?? opts
const dispatch = { name, input ->
let result = agent_dispatch_tool_call(
harness.tools,
{name: name, arguments: input},
registry,
dispatch_opts,
)
return __composition_dispatch_value(result, name)
}
const report = harness.tools.composition_execute(
snippet,
manifest,
__composition_execute_options(opts, dispatch),
)
return __composition_mcp_reduced_result(report, opts)
}
/**
* composition_mcp_tools builds the compact Code Mode MCP profile registry.
*
* @effects: []
* @errors: []
*/
pub fn composition_mcp_tools(
harness: Harness,
registry: {_type: "tool_registry", tools: list}? = nil,
options: dict? = nil,
) {
const opts = options ?? {}
const registry_source = __composition_registry(harness, opts?.tools ?? registry)
const projected_source = tool_project(registry_source, "mcp")
const source = registry_source + {tools: projected_source.tools}
const manifest_options = (opts?.manifest_options ?? opts) + {side_effect_ceiling: "read_only"}
const candidate_manifest = composition_binding_manifest(source, manifest_options)
let read_bindings = []
for binding in candidate_manifest.bindings {
if binding.side_effect_level == "read_only" {
read_bindings.push(binding)
}
}
const manifest = candidate_manifest + {bindings: read_bindings}
let tools = registry ?? tool_registry()
tools = tool_define(
tools,
"harn.code.search_examples",
"Search curated examples for governed composition snippets",
{
parameters: {
query: {type: "string", required: false},
limit: {type: "integer", required: false},
},
returns: {type: "array"},
annotations: {kind: "search", side_effect_level: "read_only", inline_result: true},
handler: { args ->
return composition_search_examples(args?.query ?? "", args?.limit ?? opts?.limit ?? 10)
},
},
)
tools = tool_define(
tools,
"harn.code.generate_harn_api",
"Generate a typed Harn Code Mode API for the server's registered tools",
{
parameters: {
tools: {type: "array", required: false},
manifest: {type: "object", required: false},
query: {type: "string", required: false},
limit: {type: "integer", required: false},
},
returns: {type: "object"},
annotations: {kind: "search", side_effect_level: "read_only", inline_result: true},
handler: { args ->
const call_args = args ?? {}
const selection = __composition_profile_selection(manifest, call_args)
if !selection.ok {
return agent_tool_handler_result(selection.error, {error: selection.error}, "error")
}
let selected = selection.manifest
let selected_names = []
for binding in selected.bindings {
selected_names.push(binding.name)
}
const names = __composition_mcp_ranked_names(
tool_select(source, selected_names),
call_args?.query,
opts + call_args,
)
if names != nil {
let named = {}
for name in names {
named[name] = true
}
let bindings = []
for binding in selected.bindings {
if named[binding.name] == true {
bindings.push(binding)
}
}
selected = selected + {bindings: bindings}
}
const result = {
manifest: selected,
harn_api: composition_harn_api(selected),
tool_count: len(selected.bindings),
servers: __composition_mcp_servers(selected),
}
return agent_tool_handler_result(to_string(result), result)
},
},
)
tools = tool_define(
tools,
"harn.code.execute_composition",
"Execute a read-only Harn composition snippet against registered tools",
{
parameters: {
snippet: {type: "string"},
manifest: {type: "object", required: false},
state: {type: "object", required: false},
session_id: {type: "string", required: false},
run_id: {type: "string", required: false},
max_operations: {type: "integer", required: false},
timeout_ms: {type: "integer", required: false},
max_output_bytes: {type: "integer", required: false},
max_concurrent: {type: "integer", required: false},
max_concurrent_per_server: {type: "integer", required: false},
trusted_servers: {
type: "array",
required: false,
description: "Server configuration only; client values are rejected.",
},
trust_annotations: {
type: "boolean",
required: false,
description: "Server configuration only; client values are rejected.",
},
call_timeout_ms: {type: "integer", required: false},
retry: {type: "object", required: false},
tools: {type: "array", required: false},
include_report: {type: "boolean", required: false},
},
returns: {type: "object"},
annotations: {kind: "think", side_effect_level: "read_only", inline_result: true},
handler: { args ->
const call_args = args ?? {}
const selection = __composition_profile_selection(manifest, call_args)
if !selection.ok {
return agent_tool_handler_result(selection.error, {error: selection.error}, "error")
}
const selected = selection.manifest
const dispatch = { name, input ->
const outcome = agent_dispatch_tool_call(
harness.tools,
{name: name, arguments: input},
source,
(opts?.dispatch_options ?? opts) + {_composition_mcp: true},
)
return __composition_dispatch_value(outcome, name)
}
const execution_opts = opts + call_args
+ {
trusted_servers: opts?.trusted_servers,
trusted_mcp_servers: opts?.trusted_mcp_servers,
trust_annotations: opts?.trust_annotations,
trust_mcp_annotations: opts?.trust_mcp_annotations,
}
const report = harness.tools.composition_execute(
call_args.snippet,
selected,
__composition_execute_options(execution_opts, dispatch),
)
const result = __composition_mcp_reduced_result(report, execution_opts)
return agent_tool_handler_result(to_string(result), result, result.ok ? "ok" : "error")
},
},
)
return tools
}
/**
* composition_crystallization_input converts a composition report into a crystallization trace.
*
* @effects: []
* @errors: []
*/
pub fn composition_crystallization_input(report: dict, options: dict? = nil) {
return composition_crystallization_trace(report, options ?? {})
}