@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.
- package/LICENSE +21 -0
- package/README.md +17 -0
- package/assets/apps/gardener/dist/gardener_runtime/assets/anthropic-messages-CpAYOexF.js +6431 -0
- package/assets/apps/gardener/dist/gardener_runtime/assets/deferred-tools-BwNJSp7E.js +31 -0
- package/assets/apps/gardener/dist/gardener_runtime/assets/error-body-D8mmocwO.js +6744 -0
- package/assets/apps/gardener/dist/gardener_runtime/assets/hash-DAk4mnwB.js +18 -0
- package/assets/apps/gardener/dist/gardener_runtime/assets/json-parse-DCA_fvRV.js +1094 -0
- package/assets/apps/gardener/dist/gardener_runtime/assets/mimetext.node.es-XQfmuX2L.js +8403 -0
- package/assets/apps/gardener/dist/gardener_runtime/assets/openai-completions-Dg9BYhy-.js +907 -0
- package/assets/apps/gardener/dist/gardener_runtime/assets/openai-prompt-cache-IAZGhS1U.js +12 -0
- package/assets/apps/gardener/dist/gardener_runtime/assets/openai-responses-shared-BptkVdeL.js +560 -0
- package/assets/apps/gardener/dist/gardener_runtime/assets/openai-responses-vjbR2NOB.js +240 -0
- package/assets/apps/gardener/dist/gardener_runtime/assets/rolldown-runtime-7_rZTKki.js +42 -0
- package/assets/apps/gardener/dist/gardener_runtime/assets/simple-options-tFhuCUzS.js +300 -0
- package/assets/apps/gardener/dist/gardener_runtime/assets/transform-messages-B41ICucH.js +246 -0
- package/assets/apps/gardener/dist/gardener_runtime/index.js +80307 -0
- package/assets/apps/gardener/migrations/0001_actions_baseline.sql +116 -0
- package/assets/gardener-distribution.json +5 -0
- package/dist/cli.js +24719 -0
- package/dist/cli.js.map +7 -0
- 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
|