feat: sync deployed v1.0.0-rc.38-custom.42

Sync production source including routing, billing, Astra detection and public uptime. Update custom build instructions and license packaging.
This commit is contained in:
cneicy committed 2026-09-26 04:49:11 +08:00
1 parent aa6c3f50f4
commit ceddfd3d6b
828 files changed
+122253 -13702

No files matched your search

+111
View File
@@ -0,0 +1,111 @@
package billingexpr
import (
"errors"
"math"
"github.com/expr-lang/expr/ast"
"github.com/expr-lang/expr/parser"
)
// DetectionCostBound proves a conservative cost ceiling rather than sampling
// a few token counts. Both conditional branches are bounded, including prices
// selected by time/request rules. Unsupported expressions fail closed.
func DetectionCostBound(expression string, input, output float64) (float64, error) {
_, body := ParseExprVersion(expression)
tree, err := parser.Parse(body)
if err != nil {
return 0, err
}
var bound func(ast.Node) (float64, error)
unsupported := errors.New("detection pricing cannot be safely bounded")
bound = func(node ast.Node) (float64, error) {
switch n := node.(type) {
case *ast.IntegerNode:
if n.Value >= 0 {
return float64(n.Value), nil
}
case *ast.FloatNode:
if n.Value >= 0 {
return n.Value, nil
}
case *ast.IdentifierNode:
switch n.Value {
case "p", "len", "cr", "cc", "cc1h":
return input, nil
case "c":
return output, nil
case "img", "img_cr", "img_o", "ai", "ao":
return 0, nil
case "image_count":
return 1, nil
}
case *ast.BinaryNode:
a, e := bound(n.Left)
if e != nil {
return 0, e
}
b, e := bound(n.Right)
if e != nil {
return 0, e
}
switch n.Operator {
case "+":
return a + b, nil
case "*":
return a * b, nil
case "/":
switch n.Right.(type) {
case *ast.IntegerNode, *ast.FloatNode:
if b > 0 {
return a / b, nil
}
}
}
case *ast.ConditionalNode:
a, e := bound(n.Exp1)
if e != nil {
return 0, e
}
b, e := bound(n.Exp2)
return max(a, b), e
case *ast.CallNode:
name, ok := n.Callee.(*ast.IdentifierNode)
if !ok {
return 0, unsupported
}
if name.Value == "tier" && len(n.Arguments) == 2 {
return bound(n.Arguments[1])
}
if name.Value == "fixed" && len(n.Arguments) == 1 {
v, e := bound(n.Arguments[0])
return v * 1_000_000, e
}
if name.Value == "ceil" && len(n.Arguments) == 1 {
v, e := bound(n.Arguments[0])
return math.Ceil(v), e
}
if name.Value == "floor" && len(n.Arguments) == 1 {
v, e := bound(n.Arguments[0])
return math.Floor(v), e
}
if name.Value == "min" || name.Value == "max" {
v := float64(0)
for _, arg := range n.Arguments {
x, e := bound(arg)
if e != nil {
return 0, e
}
v = max(v, x)
}
return v, nil
}
}
return 0, unsupported
}
value, err := bound(tree.Node)
if math.IsNaN(value) || math.IsInf(value, 0) {
return 0, unsupported
}
return value, err
}