functions

package
v0.44.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 22, 2026 License: Apache-2.0 Imports: 45 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

View Source
var AddHeaderFunc = function.New(&function.Spec{
	Description: "Returns a new response with the given header value appended",
	Params: []function.Parameter{
		{Name: "response", Type: cty.DynamicPseudoType, AllowDynamicType: true, Description: "The http_response to copy"},
		{Name: "name", Type: cty.String, Description: "Header name"},
		{Name: "value", Type: cty.String, Description: "Header value to append (existing values are kept)"},
	},
	Type: function.StaticReturnType(types.HTTPResponseObjectType),
	Impl: func(args []cty.Value, retType cty.Type) (cty.Value, error) {
		orig, ok := types.GetHTTPResponseFromValue(args[0])
		if !ok {
			return cty.NilVal, fmt.Errorf("http::add_header: first argument must be an http_response value")
		}
		r := cloneResponse(orig)
		r.Headers.Add(textproto.CanonicalMIMEHeaderKey(args[1].AsString()), args[2].AsString())
		return types.BuildHTTPResponseObject(r), nil
	},
})

AddHeaderFunc implements addheader(response, name, value). Returns a new http_response with the given header appended (multi-value safe).

View Source
var BasicAuthFunc = function.New(&function.Spec{
	Description: "Returns the value for an HTTP Basic Authorization header for the given username and password",
	Params: []function.Parameter{
		{Name: "user", Type: cty.String, Description: "Username"},
		{Name: "password", Type: cty.String, Description: "Password"},
	},
	Type: function.StaticReturnType(cty.String),
	Impl: func(args []cty.Value, retType cty.Type) (cty.Value, error) {
		user := args[0].AsString()
		password := args[1].AsString()
		encoded := base64.StdEncoding.EncodeToString([]byte(fmt.Sprintf("%s:%s", user, password)))
		return cty.StringVal("Basic " + encoded), nil
	},
})

BasicAuthFunc returns the value for an HTTP Authorization header using Basic auth

View Source
var DiffFunc = function.New(&function.Spec{
	Description: "Computes a structural diff between two values: a map describing what changed from a to b, in the form patch() applies. The result shape depends on the inputs, so it is dynamic.",
	Params: []function.Parameter{
		{Name: "a", Type: cty.DynamicPseudoType, Description: "The original value"},
		{Name: "b", Type: cty.DynamicPseudoType, Description: "The new value"},
	},
	Type: function.StaticReturnType(cty.DynamicPseudoType),
	Impl: func(args []cty.Value, retType cty.Type) (cty.Value, error) {
		a, err := go2cty2go.CtyToAny(args[0])
		if err != nil {
			return cty.UnknownVal(cty.NilType), fmt.Errorf("unable to convert first argument: %s", err)
		}
		b, err := go2cty2go.CtyToAny(args[1])
		if err != nil {
			return cty.UnknownVal(cty.NilType), fmt.Errorf("unable to convert second argument: %s", err)
		}

		diff, err := structdiff.Diff(a, b)
		if err != nil {
			return cty.UnknownVal(cty.NilType), fmt.Errorf("unable to diff values: %s", err)
		}

		return go2cty2go.AnyToCty(diff)
	},
})
View Source
var HTTPErrorFunc = function.New(&function.Spec{
	Description: "Builds an HTTP error response with the given status code and message body",
	Params: []function.Parameter{
		{Name: "status", Type: cty.Number, Description: "HTTP status code"},
		{Name: "message", Type: cty.String, Description: "Plain-text error message used as the body"},
	},
	Type: function.StaticReturnType(types.HTTPResponseObjectType),
	Impl: func(args []cty.Value, retType cty.Type) (cty.Value, error) {
		status, _ := args[0].AsBigFloat().Int64()
		r := &types.HTTPResponseWrapper{
			Status:      int(status),
			Headers:     make(http.Header),
			Body:        []byte(args[1].AsString()),
			ContentType: "text/plain; charset=utf-8",
			IsError:     true,
		}
		return types.BuildHTTPResponseObject(r), nil
	},
})

HTTPErrorFunc implements http_error(status, message). Returns an http_response value marked as an error with the given status and plain-text body.

View Source
var HTTPMustFunc = function.New(&function.Spec{
	Description: "Returns response unchanged if its status matches expected (default any 2xx); otherwise raises an HCL error",
	Params: []function.Parameter{
		{Name: "response", Type: cty.DynamicPseudoType, AllowDynamicType: true, Description: "The http_client_response to check"},
	},
	VarParam: &function.Parameter{Name: "expected", Type: cty.DynamicPseudoType, AllowNull: true, AllowDynamicType: true, Description: "Optional expected status(es): a number, an [lo, hi] range tuple, or a list mixing them (default: any 2xx)"},
	Type:     function.StaticReturnType(types.HTTPClientResponseObjectType),
	Impl: func(args []cty.Value, retType cty.Type) (cty.Value, error) {
		respVal := args[0]
		wrapper, ok := types.GetHTTPClientResponseFromValue(respVal)
		if !ok {
			return cty.NilVal, fmt.Errorf("http::must: first argument must be an http_client_response value")
		}

		check := func(status int) bool { return status >= 200 && status < 300 }
		var expectedDesc string

		if len(args) > 1 && !args[1].IsNull() {
			c, desc, err := parseHTTPMustExpected(args[1])
			if err != nil {
				return cty.NilVal, fmt.Errorf("http::must: %w", err)
			}
			check = c
			expectedDesc = desc
		} else {
			expectedDesc = "any 2xx"
		}

		if check(wrapper.R.StatusCode) {
			return respVal, nil
		}

		method := "<unknown>"
		urlStr := "<unknown>"
		if wrapper.R.Request != nil {
			if wrapper.R.Request.Method != "" {
				method = wrapper.R.Request.Method
			}
			if wrapper.R.Request.URL != nil {
				urlStr = wrapper.R.Request.URL.String()
			}
		}

		bodyExcerpt := buildHTTPMustBodyExcerpt(wrapper)

		return cty.NilVal, fmt.Errorf(
			"http::must: %s %s returned %d %s\n  expected: %s\n  body: %s",
			method,
			urlStr,
			wrapper.R.StatusCode,
			nethttp.StatusText(wrapper.R.StatusCode),
			expectedDesc,
			bodyExcerpt,
		)
	},
})

HTTPMustFunc implements http_must(response[, expected]) → response.

Returns the response unchanged when its status is acceptable; otherwise raises an HCL error containing the method, final URL, actual status, expected set, and a body excerpt.

expected may be:

  • omitted (or null) — any 2xx is acceptable
  • a single number — exact match
  • a list of numbers — any one matches
  • a list of [lo, hi] tuples — inclusive ranges
  • a mix of numbers and [lo, hi] tuples in the same list
View Source
var HTTPRedirectFunc = function.New(&function.Spec{
	Description: "Builds an HTTP redirect response; http_redirect(url) defaults to 302, http_redirect(status, url) uses the given status",
	Params: []function.Parameter{

		{Name: "first", Type: cty.DynamicPseudoType, AllowDynamicType: true, Description: "Either the redirect URL (status defaults to 302), or a status code when a URL follows"},
	},
	VarParam: &function.Parameter{Name: "rest", Type: cty.DynamicPseudoType, Description: "The redirect URL, when the first argument is a status code"},
	Type:     function.StaticReturnType(types.HTTPResponseObjectType),
	Impl: func(args []cty.Value, retType cty.Type) (cty.Value, error) {
		var status int
		var url string

		switch {
		case args[0].Type() == cty.String:
			if len(args) != 1 {
				return cty.NilVal, fmt.Errorf("http_redirect: url-only form takes exactly 1 argument")
			}
			status = http.StatusFound
			url = args[0].AsString()

		case args[0].Type() == cty.Number:
			if len(args) != 2 {
				return cty.NilVal, fmt.Errorf("http_redirect: status+url form takes exactly 2 arguments")
			}
			if args[1].Type() != cty.String {
				return cty.NilVal, fmt.Errorf("http_redirect: second argument must be a string URL, got %s", args[1].Type().FriendlyName())
			}
			s, _ := args[0].AsBigFloat().Int64()
			status = int(s)
			url = args[1].AsString()

		default:
			return cty.NilVal, fmt.Errorf("http_redirect: first argument must be a URL string or status number, got %s", args[0].Type().FriendlyName())
		}

		r := &types.HTTPResponseWrapper{
			Status:  status,
			Headers: http.Header{"Location": {url}},
		}
		return types.BuildHTTPResponseObject(r), nil
	},
})

HTTPRedirectFunc implements http_redirect(url) and http_redirect(status, url). When the first argument is a string it is treated as the URL with a default 302 status. When the first argument is a number it is treated as the status code and the second argument must be the URL string.

View Source
var HTTPResponseFunc = function.New(&function.Spec{
	Description: "Builds an HTTP response value with the given status code, optional body, and optional headers",
	Params: []function.Parameter{
		{Name: "status", Type: cty.Number, Description: "HTTP status code"},
	},
	VarParam: &function.Parameter{Name: "args", Type: cty.DynamicPseudoType, Description: "An optional body (string or bytes), then an optional headers map"},
	Type:     function.StaticReturnType(types.HTTPResponseObjectType),
	Impl: func(args []cty.Value, retType cty.Type) (cty.Value, error) {
		status, _ := args[0].AsBigFloat().Int64()
		r := &types.HTTPResponseWrapper{
			Status:  int(status),
			Headers: make(http.Header),
		}

		if len(args) > 1 {
			body, ct, err := types.CoerceBodyToBytes(args[1])
			if err != nil {
				return cty.NilVal, fmt.Errorf("http_response: invalid body: %w", err)
			}
			r.Body = body
			r.ContentType = ct
		}

		if len(args) > 2 {
			if err := applyHeadersArg(r.Headers, args[2]); err != nil {
				return cty.NilVal, fmt.Errorf("http_response: invalid headers: %w", err)
			}
		}

		return types.BuildHTTPResponseObject(r), nil
	},
})

HTTPResponseFunc implements http_response(status[, body[, headers]]).

View Source
var KillFunc = function.New(&function.Spec{
	Params: []function.Parameter{
		{Name: "pid", Type: cty.Number},
		{Name: "signal", Type: cty.Number},
	},
	Type: function.StaticReturnType(cty.Bool),
	Impl: func(args []cty.Value, retType cty.Type) (cty.Value, error) {
		pid, accuracy := args[0].AsBigFloat().Int64()
		if accuracy != 0 {
			return cty.False, fmt.Errorf("pid must be an integer")
		}
		sig, accuracy := args[1].AsBigFloat().Int64()
		if accuracy != 0 {
			return cty.False, fmt.Errorf("signal must be an integer")
		}
		if err := syscall.Kill(int(pid), syscall.Signal(sig)); err != nil {
			return cty.False, fmt.Errorf("kill(%d, %d): %w", pid, sig, err)
		}
		return cty.True, nil
	},
})

KillFunc sends a signal to a process. Both pid and signal are integers. Returns true on success, or an error if the syscall fails.

View Source
var LLMWrapFunc = function.New(&function.Spec{
	Description: "Wraps untrusted content in <user_input> delimiters as a prompt-injection mitigation; returns the wrapped string",
	Params: []function.Parameter{
		{Name: "content", Type: cty.String, Description: "The user-controlled content to wrap"},
	},
	Type: function.StaticReturnType(cty.String),
	Impl: func(args []cty.Value, retType cty.Type) (cty.Value, error) {
		content := args[0].AsString()
		return cty.StringVal("<user_input>\n" + content + "\n</user_input>"), nil
	},
})

LLMWrapFunc wraps user-controlled content in <user_input> XML-like delimiters as a prompt injection mitigation. The system prompt should reference these tags to tell the model where untrusted input begins and ends.

Input: "hello" Output: "<user_input>\nhello\n</user_input>"

View Source
var MCPAssistantMessageFunc = function.New(&function.Spec{
	Description: "Returns an assistant-role message for an MCP prompt result (few-shot example)",
	Params: []function.Parameter{
		{Name: "content", Type: cty.String, Description: "Message content"},
	},
	Type: function.StaticReturnType(MCPResultCapsuleType),
	Impl: func(args []cty.Value, retType cty.Type) (cty.Value, error) {
		return NewMCPResultCapsule(MCPResult{
			Kind: "assistant_message",
			Text: args[0].AsString(),
		}), nil
	},
})

MCPAssistantMessageFunc returns an mcp_assistantmessage function for prompt results.

View Source
var MCPErrorFunc = function.New(&function.Spec{
	Description: "Returns an error result for an MCP tool call",
	Params: []function.Parameter{
		{Name: "message", Type: cty.String, Description: "Error message"},
	},
	Type: function.StaticReturnType(MCPResultCapsuleType),
	Impl: func(args []cty.Value, retType cty.Type) (cty.Value, error) {
		return NewMCPResultCapsule(MCPResult{
			Kind: "error",
			Text: args[0].AsString(),
		}), nil
	},
})

MCPErrorFunc returns an mcp_error function that signals a tool error result.

View Source
var MCPImageFunc = function.New(&function.Spec{
	Description: "Returns image content for an MCP resource or tool result",
	Params: []function.Parameter{

		{Name: "data", Type: cty.DynamicPseudoType, AllowDynamicType: true, Description: "Base64-encoded image string or bytes capsule"},
	},
	VarParam: &function.Parameter{
		Name:        "mime_type",
		Type:        cty.String,
		Description: "MIME type of the image (required when data is a base64 string; optional when data is a bytes capsule)",
	},
	Type: function.StaticReturnType(MCPResultCapsuleType),
	Impl: func(args []cty.Value, retType cty.Type) (cty.Value, error) {
		var imageData []byte
		var mimeType string

		switch {
		case args[0].Type() == cty.String:
			var err error
			imageData, err = base64.StdEncoding.DecodeString(args[0].AsString())
			if err != nil {
				return cty.NilVal, fmt.Errorf("mcp::image: invalid base64 data: %w", err)
			}
			if len(args) < 2 {
				return cty.NilVal, fmt.Errorf("mcp::image: mime_type is required when data is a base64 string")
			}
			mimeType = args[1].AsString()
		default:
			b, err := bytescty.GetBytesFromValue(args[0])
			if err != nil {
				return cty.NilVal, fmt.Errorf("mcp::image: data must be a base64 string or bytes value, got %s", args[0].Type().FriendlyName())
			}
			imageData = b.Data
			mimeType = b.ContentType
			if len(args) > 1 {
				mimeType = args[1].AsString()
			}
		}

		return NewMCPResultCapsule(MCPResult{
			Kind:     "image",
			Data:     imageData,
			MIMEType: mimeType,
		}), nil
	},
})

MCPImageFunc returns an mcp_image function that produces image content.

Accepted call forms:

mcp_image(base64_string, mime_type)  - original form, both args required
mcp_image(bytes_capsule)             - mime_type taken from bytes content type
mcp_image(bytes_capsule, mime_type)  - mime_type overrides bytes content type
View Source
var MCPResultCapsuleType = cty.CapsuleWithOps("mcp_result", reflect.TypeOf(MCPResult{}), &cty.CapsuleOps{
	GoString: func(val interface{}) string {
		r := val.(*MCPResult)
		return fmt.Sprintf("mcp_result(%s)", r.Kind)
	},
	TypeGoString: func(_ reflect.Type) string {
		return "mcp_result"
	},
})

MCPResultCapsuleType is the cty capsule type for MCPResult values.

View Source
var MCPUserMessageFunc = function.New(&function.Spec{
	Description: "Returns a user-role message for an MCP prompt result",
	Params: []function.Parameter{
		{Name: "content", Type: cty.String, Description: "Message content"},
	},
	Type: function.StaticReturnType(MCPResultCapsuleType),
	Impl: func(args []cty.Value, retType cty.Type) (cty.Value, error) {
		return NewMCPResultCapsule(MCPResult{
			Kind: "user_message",
			Text: args[0].AsString(),
		}), nil
	},
})

MCPUserMessageFunc returns an mcp_usermessage function for prompt results.

View Source
var PatchFunc = function.New(&function.Spec{
	Description: "Applies a structural diff (from diff()) to a target map, returning the patched map. The result shape depends on the inputs, so it is dynamic.",
	Params: []function.Parameter{
		{Name: "target", Type: cty.DynamicPseudoType, Description: "The map to patch"},
		{Name: "patch", Type: cty.DynamicPseudoType, Description: "The diff to apply (a map, as produced by diff())"},
	},
	Type: function.StaticReturnType(cty.DynamicPseudoType),
	Impl: func(args []cty.Value, retType cty.Type) (cty.Value, error) {
		target, err := go2cty2go.CtyToAny(args[0])
		if err != nil {
			return cty.UnknownVal(cty.NilType), fmt.Errorf("unable to convert target argument: %s", err)
		}
		patch, err := go2cty2go.CtyToAny(args[1])
		if err != nil {
			return cty.UnknownVal(cty.NilType), fmt.Errorf("unable to convert patch argument: %s", err)
		}

		patchMap, ok := patch.(map[string]any)
		if !ok {
			return cty.UnknownVal(cty.NilType), fmt.Errorf("patch must be a map")
		}

		targetMap, ok := target.(map[string]any)
		if !ok {
			return cty.UnknownVal(cty.NilType), fmt.Errorf("target must be a map")
		}

		err = structdiff.Apply(&targetMap, patchMap)
		if err != nil {
			return cty.UnknownVal(cty.NilType), fmt.Errorf("unable to apply patch: %s", err)
		}

		return go2cty2go.AnyToCty(targetMap)
	},
})
View Source
var RemoveHeaderFunc = function.New(&function.Spec{
	Description: "Returns a new response with all values for the given header removed",
	Params: []function.Parameter{
		{Name: "response", Type: cty.DynamicPseudoType, AllowDynamicType: true, Description: "The http_response to copy"},
		{Name: "name", Type: cty.String, Description: "Header name to remove (all its values)"},
	},
	Type: function.StaticReturnType(types.HTTPResponseObjectType),
	Impl: func(args []cty.Value, retType cty.Type) (cty.Value, error) {
		orig, ok := types.GetHTTPResponseFromValue(args[0])
		if !ok {
			return cty.NilVal, fmt.Errorf("http::remove_header: first argument must be an http_response value")
		}
		r := cloneResponse(orig)
		r.Headers.Del(args[1].AsString())
		return types.BuildHTTPResponseObject(r), nil
	},
})

RemoveHeaderFunc implements removeheader(response, name). Returns a new http_response with all values for the given header removed.

View Source
var SQLMustFunc = function.New(&function.Spec{
	Description: "Returns a SQL result unchanged if it carries no error; otherwise raises an HCL error. Its return type echoes the result passed in.",
	Params: []function.Parameter{
		{
			Name:             "result",
			Type:             cty.DynamicPseudoType,
			AllowNull:        true,
			AllowDynamicType: true,
			Description:      "A SQL result object (must have an \"error\" field)",
		},
	},
	Type: func(args []cty.Value) (cty.Type, error) {
		return args[0].Type(), nil
	},
	Impl: func(args []cty.Value, retType cty.Type) (cty.Value, error) {
		result := args[0]
		if !result.IsKnown() {
			return cty.UnknownVal(retType), nil
		}
		if result.IsNull() || !result.Type().IsObjectType() || !result.Type().HasAttribute("error") {
			return cty.NilVal, fmt.Errorf("sql::must: argument is not a result object (no \"error\" field)")
		}

		errVal := result.GetAttr("error")
		if errVal.IsNull() {
			return result, nil
		}

		return cty.NilVal, fmt.Errorf("sql::must: %s", formatSQLError(errVal))
	},
})

SQLMustFunc turns the "error rides in the result object" convention used by SQL `call()` into a fail-fast: given a result object, if its `error` field is non-null it raises an evaluation error built from the error fields; otherwise it returns the result unchanged.

# branch on the error...
r = call(ctx, client.db, "INSERT ...")
# ...or just fail the action if it errored:
r = sql_must(call(ctx, client.db, "INSERT ..."))
View Source
var SetCookieFunc = function.New(&function.Spec{
	Description: "Formats a Set-Cookie header value from a cookie definition object",
	Params: []function.Parameter{
		{Name: "cookie", Type: cty.DynamicPseudoType, AllowDynamicType: true, Description: "Cookie object: name and value are required; path, domain, max_age, secure, http_only, same_site, etc. are optional"},
	},
	Type: function.StaticReturnType(cty.String),
	Impl: func(args []cty.Value, retType cty.Type) (cty.Value, error) {
		val := args[0]
		if !val.Type().IsObjectType() {
			return cty.NilVal, fmt.Errorf("http::set_cookie: argument must be an object, got %s", val.Type().FriendlyName())
		}

		if !val.Type().HasAttribute("name") || !val.Type().HasAttribute("value") {
			return cty.NilVal, fmt.Errorf("http::set_cookie: object must have 'name' and 'value' attributes")
		}

		c := &http.Cookie{
			Name:  val.GetAttr("name").AsString(),
			Value: val.GetAttr("value").AsString(),
		}

		if val.Type().HasAttribute("path") {
			c.Path = val.GetAttr("path").AsString()
		}
		if val.Type().HasAttribute("domain") {
			c.Domain = val.GetAttr("domain").AsString()
		}
		if val.Type().HasAttribute("expires") {
			exp := val.GetAttr("expires")
			switch {
			case exp.Type() == timecty.TimeCapsuleType:
				t, _ := timecty.GetTime(exp)
				c.Expires = t
			case exp.Type() == timecty.DurationCapsuleType:
				d, _ := timecty.GetDuration(exp)
				c.Expires = time.Now().Add(d)
			case exp.Type() == cty.String:
				s := exp.AsString()
				if s != "" {
					t, err := time.Parse(time.RFC3339, s)
					if err != nil {
						return cty.NilVal, fmt.Errorf("http::set_cookie: invalid expires value %q: %w", s, err)
					}
					c.Expires = t
				}
			default:
				return cty.NilVal, fmt.Errorf("http::set_cookie: expires must be a time, duration, or RFC3339 string, got %s", exp.Type().FriendlyName())
			}
		}
		if val.Type().HasAttribute("max_age") {
			f, _ := val.GetAttr("max_age").AsBigFloat().Int64()
			c.MaxAge = int(f)
		}
		if val.Type().HasAttribute("secure") {
			c.Secure = val.GetAttr("secure").True()
		}
		if val.Type().HasAttribute("http_only") {
			c.HttpOnly = val.GetAttr("http_only").True()
		}
		if val.Type().HasAttribute("same_site") {
			switch strings.ToLower(val.GetAttr("same_site").AsString()) {
			case "strict":
				c.SameSite = http.SameSiteStrictMode
			case "lax":
				c.SameSite = http.SameSiteLaxMode
			case "none":
				c.SameSite = http.SameSiteNoneMode
			default:
				c.SameSite = http.SameSiteDefaultMode
			}
		}
		if val.Type().HasAttribute("partitioned") {
			c.Partitioned = val.GetAttr("partitioned").True()
		}

		return cty.StringVal(c.String()), nil
	},
})

SetCookieFunc implements setcookie(cookieObj). Formats a Set-Cookie header value from an object with cookie fields. The name and value fields are required; all others are optional.

Functions

func GetHTTPClientFunctions added in v0.26.0

func GetHTTPClientFunctions(config *cfg.Config) map[string]function.Function

GetHTTPClientFunctions returns the eight http_* verb functions, capturing the supplied config so verb functions can evaluate lazy expressions like retry.on_response against the same eval context the rest of vinculum uses. config may be nil in tests that do not exercise hooks.

func GetHTTPResponseFunctions added in v0.20.0

func GetHTTPResponseFunctions() map[string]function.Function

GetHTTPResponseFunctions returns all HTTP response functions for global registration.

func GetLogFunctions

func GetLogFunctions(logger *zap.Logger) map[string]function.Function

GetLogFunctions returns HCL functions for logging with zap logger

func GetMcpFunctions added in v0.10.0

func GetMcpFunctions() map[string]function.Function

GetMcpFunctions returns all MCP-specific cty functions. These are included in the global function set so they are available in any action expression, including bus subscriptions that construct MCP values for async handlers.

func GetStandardLibraryFunctions

func GetStandardLibraryFunctions() map[string]function.Function

GetStandardLibraryFunctions returns a map of all cty standard library functions suitable for providing to an HCL evaluation context.

func MakeFileAppendFunc added in v0.15.0

func MakeFileAppendFunc(baseDir string) function.Function

MakeFileAppendFunc constructs a function that appends a string to a file, creating the file if it does not exist. The path must be within baseDir.

func MakeFileBytesFunc added in v0.19.0

func MakeFileBytesFunc(baseDir string) function.Function

MakeFileBytesFunc returns a filebytes function restricted to baseDir. filebytes(path) or filebytes(path, content_type)

func MakeFileWriteFunc added in v0.15.0

func MakeFileWriteFunc(baseDir string) function.Function

MakeFileWriteFunc constructs a function that writes a string to a file, creating or overwriting it. The path must be within baseDir.

func MakeGoTemplateFileFunc added in v0.15.0

func MakeGoTemplateFileFunc(
	baseDir string,
	constants map[string]cty.Value,
) function.Function

MakeGoTemplateFileFunc constructs a gotemplatefile(path, vars) function. It reads a Go text/template file, evaluates it with the given vars merged on top of the standard VCL constants (env, sys, var, metric, etc.), and returns the rendered string. The path is resolved relative to baseDir.

constants is the live Config.Constants map. Unlike templatefile(), no funcsGetter is needed because Go templates use their own FuncMap.

func MakeTemplateFileFunc added in v0.15.0

func MakeTemplateFileFunc(
	baseDir string,
	constants map[string]cty.Value,
	funcsGetter func() map[string]function.Function,
) function.Function

MakeTemplateFileFunc constructs a templatefile(path, vars) function. It reads an HCL template file, evaluates it with the given vars merged into the standard VCL variable scope (env, sys, var, metric, etc.), and returns the result. The path is resolved relative to baseDir.

constants is the live Config.Constants map (captured by reference so that var/metric/bus/server/client entries added during block processing are visible at evaluation time). funcsGetter returns all available functions excluding templatefile itself, preventing recursion.

func NewMCPResultCapsule added in v0.10.0

func NewMCPResultCapsule(r MCPResult) cty.Value

NewMCPResultCapsule wraps an MCPResult in a cty capsule value.

Types

type MCPResult added in v0.10.0

type MCPResult struct {
	// Kind is one of: "image", "error", "user_message", "assistant_message"
	Kind     string
	Text     string
	Data     []byte // decoded bytes for images
	MIMEType string
}

MCPResult holds typed return values from MCP action expressions. It is wrapped in a cty capsule so it can pass through HCL evaluation.

func GetMCPResult added in v0.10.0

func GetMCPResult(val cty.Value) *MCPResult

GetMCPResult extracts an MCPResult from a cty capsule value. Returns nil if the value is not an MCPResult capsule.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL