@scuffi/gardener 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (21) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +17 -0
  3. package/assets/apps/gardener/dist/gardener_runtime/assets/anthropic-messages-CpAYOexF.js +6431 -0
  4. package/assets/apps/gardener/dist/gardener_runtime/assets/deferred-tools-BwNJSp7E.js +31 -0
  5. package/assets/apps/gardener/dist/gardener_runtime/assets/error-body-D8mmocwO.js +6744 -0
  6. package/assets/apps/gardener/dist/gardener_runtime/assets/hash-DAk4mnwB.js +18 -0
  7. package/assets/apps/gardener/dist/gardener_runtime/assets/json-parse-DCA_fvRV.js +1094 -0
  8. package/assets/apps/gardener/dist/gardener_runtime/assets/mimetext.node.es-XQfmuX2L.js +8403 -0
  9. package/assets/apps/gardener/dist/gardener_runtime/assets/openai-completions-Dg9BYhy-.js +907 -0
  10. package/assets/apps/gardener/dist/gardener_runtime/assets/openai-prompt-cache-IAZGhS1U.js +12 -0
  11. package/assets/apps/gardener/dist/gardener_runtime/assets/openai-responses-shared-BptkVdeL.js +560 -0
  12. package/assets/apps/gardener/dist/gardener_runtime/assets/openai-responses-vjbR2NOB.js +240 -0
  13. package/assets/apps/gardener/dist/gardener_runtime/assets/rolldown-runtime-7_rZTKki.js +42 -0
  14. package/assets/apps/gardener/dist/gardener_runtime/assets/simple-options-tFhuCUzS.js +300 -0
  15. package/assets/apps/gardener/dist/gardener_runtime/assets/transform-messages-B41ICucH.js +246 -0
  16. package/assets/apps/gardener/dist/gardener_runtime/index.js +80307 -0
  17. package/assets/apps/gardener/migrations/0001_actions_baseline.sql +116 -0
  18. package/assets/gardener-distribution.json +5 -0
  19. package/dist/cli.js +24719 -0
  20. package/dist/cli.js.map +7 -0
  21. package/package.json +45 -0
@@ -0,0 +1,246 @@
1
+ //#region ../../node_modules/.pnpm/@earendil-works+pi-ai@0.83.0_@modelcontextprotocol+sdk@1.30.0_@cfworker+json-schema@4.1_c038161535a4cc121d37390bb491fb78/node_modules/@earendil-works/pi-ai/dist/utils/sanitize-unicode.js
2
+ /**
3
+ * Removes unpaired Unicode surrogate characters from a string.
4
+ *
5
+ * Unpaired surrogates (high surrogates 0xD800-0xDBFF without matching low surrogates 0xDC00-0xDFFF,
6
+ * or vice versa) cause JSON serialization errors in many API providers.
7
+ *
8
+ * Valid emoji and other characters outside the Basic Multilingual Plane use properly paired
9
+ * surrogates and will NOT be affected by this function.
10
+ *
11
+ * @param text - The text to sanitize
12
+ * @returns The sanitized text with unpaired surrogates removed
13
+ *
14
+ * @example
15
+ * // Valid emoji (properly paired surrogates) are preserved
16
+ * sanitizeSurrogates("Hello 🙈 World") // => "Hello 🙈 World"
17
+ *
18
+ * // Unpaired high surrogate is removed
19
+ * const unpaired = String.fromCharCode(0xD83D); // high surrogate without low
20
+ * sanitizeSurrogates(`Text ${unpaired} here`) // => "Text here"
21
+ */
22
+ function sanitizeSurrogates(text) {
23
+ return text.replace(/[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?<![\uD800-\uDBFF])[\uDC00-\uDFFF]/g, "");
24
+ }
25
+ //#endregion
26
+ //#region ../../node_modules/.pnpm/@earendil-works+pi-ai@0.83.0_@modelcontextprotocol+sdk@1.30.0_@cfworker+json-schema@4.1_c038161535a4cc121d37390bb491fb78/node_modules/@earendil-works/pi-ai/dist/api/constrained-sampling.js
27
+ function getGrammarToolInput(toolName, arguments_, inputProperty) {
28
+ const input = arguments_[inputProperty];
29
+ if (typeof input !== "string") throw new Error(`Grammar tool call "${toolName}" requires argument "${inputProperty}" to be a string.`);
30
+ return input;
31
+ }
32
+ function appendGrammarToolInputJsonDelta(buffer, inputProperty, nextInput, close) {
33
+ if (buffer.closed) {
34
+ if (close && nextInput === buffer.input) return void 0;
35
+ throw new Error(`grammar tool input for property "${inputProperty}" changed after it was closed`);
36
+ }
37
+ if (!nextInput.startsWith(buffer.input)) throw new Error(`grammar tool input for property "${inputProperty}" changed non-monotonically`);
38
+ const inputDelta = nextInput.slice(buffer.input.length);
39
+ if (!close && inputDelta.length === 0) return void 0;
40
+ let delta = "";
41
+ if (!buffer.started) {
42
+ delta += `{${JSON.stringify(inputProperty)}:"`;
43
+ buffer.started = true;
44
+ }
45
+ delta += JSON.stringify(inputDelta).slice(1, -1);
46
+ buffer.input = nextInput;
47
+ if (close) {
48
+ delta += "\"}";
49
+ buffer.closed = true;
50
+ }
51
+ return delta;
52
+ }
53
+ function inferGrammarInputProperty(tool) {
54
+ const schema = tool.parameters;
55
+ if (schema.type !== "object") throw new Error("grammar constrained sampling requires an object parameter schema");
56
+ if (!Array.isArray(schema.required) || schema.required.length !== 1 || typeof schema.required[0] !== "string") throw new Error("grammar constrained sampling requires exactly one required string property");
57
+ const inputProperty = schema.required[0];
58
+ if (!schema.properties?.[inputProperty]) throw new Error(`grammar constrained sampling requires a properties entry for ${inputProperty}`);
59
+ if (schema.properties[inputProperty]?.type !== "string") throw new Error(`grammar constrained sampling property ${inputProperty} must have type string`);
60
+ return inputProperty;
61
+ }
62
+ function resolveJsonSchemaStrictSampling(tool, supportsStrictMode) {
63
+ const config = tool.constrainedSampling;
64
+ if (!config || config.type !== "json_schema") return;
65
+ if (supportsStrictMode) return true;
66
+ if (config.strict === "require") throw new Error(`Tool "${tool.name}" requires JSON-schema constrained sampling, but strict tools are unsupported.`);
67
+ }
68
+ function resolveGrammarConstrainedSampling(tool, supportsOpenAIGrammarTools) {
69
+ const config = tool.constrainedSampling;
70
+ if (!config || config.type !== "grammar") return;
71
+ if (!supportsOpenAIGrammarTools) return;
72
+ const larkDefinition = config.variants.openai_lark;
73
+ const regexDefinition = config.variants.openai_regex;
74
+ const hasLarkDefinition = typeof larkDefinition === "string" && larkDefinition.trim().length > 0;
75
+ const hasRegexDefinition = typeof regexDefinition === "string" && regexDefinition.trim().length > 0;
76
+ if (!hasLarkDefinition && !hasRegexDefinition) throw new Error(`Tool "${tool.name}" cannot use grammar constrained sampling: no supported grammar variant was provided.`);
77
+ try {
78
+ return {
79
+ format: hasLarkDefinition ? "lark" : "regex",
80
+ definition: hasLarkDefinition ? larkDefinition : regexDefinition,
81
+ inputProperty: inferGrammarInputProperty(tool)
82
+ };
83
+ } catch (error) {
84
+ const message = error instanceof Error ? error.message : String(error);
85
+ throw new Error(`Tool "${tool.name}" cannot use grammar constrained sampling: ${message}.`);
86
+ }
87
+ }
88
+ function createGrammarToolInputProperties(tools, supportsOpenAIGrammarTools) {
89
+ const properties = /* @__PURE__ */ new Map();
90
+ for (const tool of tools ?? []) {
91
+ const grammar = resolveGrammarConstrainedSampling(tool, supportsOpenAIGrammarTools);
92
+ if (grammar) properties.set(tool.name, grammar.inputProperty);
93
+ }
94
+ return properties;
95
+ }
96
+ //#endregion
97
+ //#region ../../node_modules/.pnpm/@earendil-works+pi-ai@0.83.0_@modelcontextprotocol+sdk@1.30.0_@cfworker+json-schema@4.1_c038161535a4cc121d37390bb491fb78/node_modules/@earendil-works/pi-ai/dist/api/transform-messages.js
98
+ var NON_VISION_USER_IMAGE_PLACEHOLDER = "(image omitted: model does not support images)";
99
+ var NON_VISION_TOOL_IMAGE_PLACEHOLDER = "(tool image omitted: model does not support images)";
100
+ function replaceImagesWithPlaceholder(content, placeholder) {
101
+ const result = [];
102
+ let previousWasPlaceholder = false;
103
+ for (const block of content) {
104
+ if (block.type === "image") {
105
+ if (!previousWasPlaceholder) result.push({
106
+ type: "text",
107
+ text: placeholder
108
+ });
109
+ previousWasPlaceholder = true;
110
+ continue;
111
+ }
112
+ result.push(block);
113
+ previousWasPlaceholder = block.text === placeholder;
114
+ }
115
+ return result;
116
+ }
117
+ function downgradeUnsupportedImages(messages, model) {
118
+ if (model.input.includes("image")) return messages;
119
+ return messages.map((msg) => {
120
+ if (msg.role === "user" && Array.isArray(msg.content)) return {
121
+ ...msg,
122
+ content: replaceImagesWithPlaceholder(msg.content, NON_VISION_USER_IMAGE_PLACEHOLDER)
123
+ };
124
+ if (msg.role === "toolResult") return {
125
+ ...msg,
126
+ content: replaceImagesWithPlaceholder(msg.content, NON_VISION_TOOL_IMAGE_PLACEHOLDER)
127
+ };
128
+ return msg;
129
+ });
130
+ }
131
+ /**
132
+ * Normalize tool call ID for cross-provider compatibility.
133
+ * OpenAI Responses API generates IDs that are 450+ chars with special characters like `|`.
134
+ * Anthropic APIs require IDs matching ^[a-zA-Z0-9_-]+$ (max 64 chars).
135
+ */
136
+ function transformMessages(messages, model, normalizeToolCallId) {
137
+ const toolCallIdMap = /* @__PURE__ */ new Map();
138
+ const transformed = downgradeUnsupportedImages(messages.map((msg) => msg.content == null ? {
139
+ ...msg,
140
+ content: []
141
+ } : msg), model).map((msg) => {
142
+ if (msg.role === "user") return msg;
143
+ if (msg.role === "toolResult") {
144
+ const normalizedId = toolCallIdMap.get(msg.toolCallId);
145
+ if (normalizedId && normalizedId !== msg.toolCallId) return {
146
+ ...msg,
147
+ toolCallId: normalizedId
148
+ };
149
+ return msg;
150
+ }
151
+ if (msg.role === "assistant") {
152
+ const assistantMsg = msg;
153
+ const isSameModel = assistantMsg.provider === model.provider && assistantMsg.api === model.api && assistantMsg.model === model.id;
154
+ const transformedContent = assistantMsg.content.flatMap((block) => {
155
+ if (block.type === "thinking") {
156
+ if (block.redacted) return isSameModel ? block : [];
157
+ if (isSameModel && block.thinkingSignature) return block;
158
+ if (!block.thinking || block.thinking.trim() === "") return [];
159
+ if (isSameModel) return block;
160
+ return {
161
+ type: "text",
162
+ text: block.thinking
163
+ };
164
+ }
165
+ if (block.type === "text") {
166
+ if (isSameModel) return block;
167
+ return {
168
+ type: "text",
169
+ text: block.text
170
+ };
171
+ }
172
+ if (block.type === "toolCall") {
173
+ const toolCall = block;
174
+ let normalizedToolCall = toolCall;
175
+ if (!isSameModel && toolCall.thoughtSignature) {
176
+ normalizedToolCall = { ...toolCall };
177
+ delete normalizedToolCall.thoughtSignature;
178
+ }
179
+ if (!isSameModel && normalizeToolCallId) {
180
+ const normalizedId = normalizeToolCallId(toolCall.id, model, assistantMsg);
181
+ if (normalizedId !== toolCall.id) {
182
+ toolCallIdMap.set(toolCall.id, normalizedId);
183
+ normalizedToolCall = {
184
+ ...normalizedToolCall,
185
+ id: normalizedId
186
+ };
187
+ }
188
+ }
189
+ return normalizedToolCall;
190
+ }
191
+ return block;
192
+ });
193
+ return {
194
+ ...assistantMsg,
195
+ content: transformedContent
196
+ };
197
+ }
198
+ return msg;
199
+ });
200
+ const result = [];
201
+ let pendingToolCalls = [];
202
+ let existingToolResultIds = /* @__PURE__ */ new Set();
203
+ const insertSyntheticToolResults = () => {
204
+ if (pendingToolCalls.length > 0) {
205
+ for (const tc of pendingToolCalls) if (!existingToolResultIds.has(tc.id)) result.push({
206
+ role: "toolResult",
207
+ toolCallId: tc.id,
208
+ toolName: tc.name,
209
+ content: [{
210
+ type: "text",
211
+ text: "No result provided"
212
+ }],
213
+ isError: true,
214
+ timestamp: Date.now()
215
+ });
216
+ pendingToolCalls = [];
217
+ existingToolResultIds = /* @__PURE__ */ new Set();
218
+ }
219
+ };
220
+ for (let i = 0; i < transformed.length; i++) {
221
+ const msg = transformed[i];
222
+ if (msg.role === "assistant") {
223
+ insertSyntheticToolResults();
224
+ const assistantMsg = msg;
225
+ if (assistantMsg.stopReason === "error" || assistantMsg.stopReason === "aborted") continue;
226
+ const toolCalls = assistantMsg.content.filter((b) => b.type === "toolCall");
227
+ if (toolCalls.length > 0) {
228
+ pendingToolCalls = toolCalls;
229
+ existingToolResultIds = /* @__PURE__ */ new Set();
230
+ }
231
+ result.push(msg);
232
+ } else if (msg.role === "toolResult") {
233
+ existingToolResultIds.add(msg.toolCallId);
234
+ result.push(msg);
235
+ } else if (msg.role === "user") {
236
+ insertSyntheticToolResults();
237
+ result.push(msg);
238
+ } else result.push(msg);
239
+ }
240
+ insertSyntheticToolResults();
241
+ return result;
242
+ }
243
+ //#endregion
244
+ export { resolveGrammarConstrainedSampling as a, getGrammarToolInput as i, appendGrammarToolInputJsonDelta as n, resolveJsonSchemaStrictSampling as o, createGrammarToolInputProperties as r, sanitizeSurrogates as s, transformMessages as t };
245
+
246
+ //# sourceMappingURL=transform-messages-B41ICucH.js.map