char-slop/berry

multipurpose self-modifiable agentic harness

git clone https://git.t4t.associates/char-slop/berry

Charlotte SomOrder extension configuration consistently in new conversationsbcca6b5

main
4.6 KiB153 linesraw
1import { defineExtension } from "@berry/api";
2import { type Static, Type } from "@earendil-works/pi-ai";
3
4const parameters = Type.Object({
5  sort: Type.Union([
6    Type.Literal("default"),
7    Type.Literal("throughput"),
8    Type.Literal("latency"),
9    Type.Literal("price"),
10  ], {
11    title: "Sort providers",
12    description: "throughput is Nitro routing; default preserves the model's routing.",
13    default: "default",
14  }),
15  only: Type.String({
16    title: "Allowed providers",
17    description:
18      "Comma-separated endpoint tags, e.g. baseten/fast. Blank preserves model defaults.",
19    default: "",
20  }),
21  ignore: Type.String({
22    title: "Excluded providers",
23    description: "Comma-separated provider or endpoint tags.",
24    default: "",
25  }),
26  maxPromptPrice: Type.String({
27    title: "Maximum input price ($/M tokens)",
28    description: "Nonnegative USD per million tokens; blank preserves model defaults.",
29    default: "",
30  }),
31  maxCompletionPrice: Type.String({
32    title: "Maximum output price ($/M tokens)",
33    description: "Nonnegative USD per million tokens; blank preserves model defaults.",
34    default: "",
35  }),
36  allowFallbacks: Type.Union([
37    Type.Literal("default"),
38    Type.Literal("yes"),
39    Type.Literal("no"),
40  ], {
41    title: "Allow provider fallbacks",
42    description: "Fallbacks still have to satisfy the allowlist, exclusions, and price caps.",
43    default: "default",
44  }),
45}, { additionalProperties: false });
46
47type State = Static<typeof parameters>;
48type Event = { type: "configured"; values: State };
49type Routing = {
50  sort?: "throughput" | "latency" | "price";
51  only?: string[];
52  ignore?: string[];
53  max_price?: { prompt?: number; completion?: number };
54  allow_fallbacks?: boolean;
55};
56
57/** The editable fields, since an event recorded before one was dropped still carries it. */
58function settings(state: State): State {
59  return {
60    sort: state.sort,
61    only: state.only,
62    ignore: state.ignore,
63    maxPromptPrice: state.maxPromptPrice,
64    maxCompletionPrice: state.maxCompletionPrice,
65    allowFallbacks: state.allowFallbacks,
66  };
67}
68
69function routing(values: State): Routing {
70  const result: Routing = {};
71  if (values.sort !== "default") result.sort = values.sort;
72  for (const key of ["only", "ignore"] as const) {
73    const tags = [
74      ...new Set(
75        values[key].split(",").map((tag) => tag.trim()).filter(Boolean),
76      ),
77    ];
78    if (tags.length) result[key] = tags;
79  }
80  for (
81    const [field, key] of [
82      ["maxPromptPrice", "prompt"],
83      ["maxCompletionPrice", "completion"],
84    ] as const
85  ) {
86    const text = values[field].trim();
87    if (!text) continue;
88    const price = Number(text);
89    if (!/^(?:\d+(?:\.\d*)?|\.\d+)$/.test(text) || !Number.isFinite(price)) {
90      throw new Error(
91        `${
92          key === "prompt" ? "Input" : "Output"
93        } price must be a nonnegative decimal in $/M tokens.`,
94      );
95    }
96    (result.max_price ??= {})[key] = price;
97  }
98  if (values.allowFallbacks !== "default") {
99    result.allow_fallbacks = values.allowFallbacks === "yes";
100  }
101  return result;
102}
103
104function isObject(value: unknown): value is Record<string, unknown> {
105  return typeof value === "object" && value !== null && !Array.isArray(value);
106}
107
108export default defineExtension<State, Event>({
109  name: "openrouter-routing",
110  description: "per-conversation OpenRouter provider routing and price limits",
111  alwaysOn: true,
112  sortOrder: -1000,
113  initial: () => ({
114    sort: "default",
115    only: "",
116    ignore: "",
117    maxPromptPrice: "",
118    maxCompletionPrice: "",
119    allowFallbacks: "default",
120  }),
121  apply: (state, event) =>
122    event.type === "configured" ? settings({ ...state, ...event.values }) : state,
123  setup(ext) {
124    ext.configuration({
125      parameters,
126      values: (state) => settings(state),
127      events(values, state) {
128        routing(values);
129        return Object.keys(values).every((key) =>
130            values[key as keyof State] === state[key as keyof State]
131          )
132          ? []
133          : [{ type: "configured", values }];
134      },
135    });
136    return (conv) => {
137      const requirements = routing(settings(conv.state));
138      if (!Object.keys(requirements).length) return;
139      conv.onPayload((payload, model) => {
140        if (model.provider !== "openrouter" || !isObject(payload)) return;
141        const existing = isObject(payload.provider) ? payload.provider : {};
142        const provider = { ...existing, ...requirements };
143        if (requirements.max_price) {
144          provider.max_price = {
145            ...(isObject(existing.max_price) ? existing.max_price : {}),
146            ...requirements.max_price,
147          };
148        }
149        return { ...payload, provider };
150      });
151    };
152  },
153});