Lua 独立消费者¶
在自己的应用中使用已发布的 LuaRocks praxo-core 0.6.0-1,要求 Lua 5.4。
无需检出 PRAXO-CORE 源码、API Key、模型服务或 AxisVela 产品。安装需要 LuaRocks
访问或已有 rock 缓存。
这是扩展语言 starter,只演示 allow/deny 路径,不在四个具备治理负向矩阵的试点语言范围内。
选择边界¶
适用于需要显式工具范围和 Policy 的嵌入式模型/工具循环。应用仍负责模型访问、真实身份、 持久审批、外部效果和隔离。它不是托管 Agent 平台、持久图引擎或沙箱服务。 选型前阅读何时不应选择 Core。
在新应用安装¶
luarocks install praxo-core 0.7.0-1
验收时不要把仓库的 language/lua 目录加入 package.path,也不要使用本地 rockspec
或源码检出。starter 里保留源码回退路径,只是为了让本仓库无需 LuaRocks 也能运行同一文件;
真实消费者应安装 rock。
应用源码¶
以下为 starter.lua,来自受测源码。
local script_dir = (arg and arg[0] and arg[0]:match("^(.*)[/\\][^/\\]*$")) or "."
package.path = table.concat({
script_dir .. "/../../language/lua/?.lua",
script_dir .. "/../../language/lua/?/init.lua",
"language/lua/?.lua",
"language/lua/?/init.lua",
"./?.lua",
package.path,
}, ";")
local agent = require("praxo.agent")
local errors = require("praxo.errors")
local models = require("praxo.models")
local M = {}
local function fixture_model(target)
return {
generate = function(request)
local last = request.messages[#request.messages]
if last.role == models.TOOL then
return models.response({ message = models.message_assistant("recorded") })
end
local call = models.tool_call({
id = "record-1",
name = "record",
arguments = { target = target },
})
return models.response({
message = models.message_assistant("", { call }),
})
end,
}
end
function M.run_scenario(target)
local calls = 0
local registry = agent.tool_registry()
agent.register_tool(registry, agent.func_tool("record", "Record a target.", function(_arguments)
calls = calls + 1
return "recorded"
end))
local options = agent.agent_options(fixture_model(target))
options.tools = registry
options.allowed_tools = { "record" }
options.policy = function(action)
if action.kind == "model.generate" then
return { allowed = true, reason = "model generation" }
elseif action.kind == "tool.invoke" then
return {
allowed = action.tool_name == "record" and action.arguments.target == "public",
reason = "only the public target is permitted",
}
end
return { allowed = false, reason = "unsupported action" }
end
local ok, result = pcall(agent.run_agent, options,
models.session({ id = "consumer-" .. target }), "Record the requested target.")
if not ok then
return "", calls, errors.code(result)
end
return result.output, calls, nil
end
function M.run()
local output, calls, code = M.run_scenario("public")
assert(code == nil and output == "recorded" and calls == 1, "allow verification failed")
print("allow: recorded; effects=1")
local _, deny_calls, deny_code = M.run_scenario("private")
assert(deny_code == "AGENT_POLICY_DENIED" and deny_calls == 0, "deny verification failed")
print("deny: policy rejected; effects=0")
end
return M
验收测试¶
以下为 test_starter.lua,来自受测源码。
local script_dir = (arg and arg[0] and arg[0]:match("^(.*)[/\\][^/\\]*$")) or "."
local starter = dofile(script_dir .. "/starter.lua")
local output, calls, code = starter.run_scenario("public")
assert(code == nil and output == "recorded" and calls == 1, "allow verification failed")
local _, deny_calls, deny_code = starter.run_scenario("private")
assert(deny_code == "AGENT_POLICY_DENIED" and deny_calls == 0, "deny verification failed")
print("lua consumer tests passed")
验证¶
luarocks install praxo-core 0.7.0-1
lua test_starter.lua
程序预期输出:
allow: recorded; effects=1
deny: policy rejected; effects=0
模型是确定性 fixture,不是真实 LLM。allowed_tools 限制工具名,Policy 额外检查目标
参数。被拒绝的 private 目标抛出 AGENT_POLICY_DENIED,且不得增加内存计数器。
替换为真实适配器后仍需保留这些测试。
范围¶
本 starter 仅证明指定 rock 与 fixture 行为,不包含治理负向矩阵,也不证明真实身份、 持久审批、效果对账或隔离。后续参考 Lua 实现指南及 安全模型。