@ottocode/sdk 0.1.242 → 0.1.244
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/package.json +1 -1
- package/src/core/src/tools/builtin/bash.txt +9 -4
- package/src/core/src/tools/builtin/finish.txt +12 -7
- package/src/core/src/tools/builtin/glob.txt +9 -6
- package/src/core/src/tools/builtin/patch.txt +120 -11
- package/src/core/src/tools/builtin/progress.txt +20 -3
- package/src/core/src/tools/builtin/ripgrep.txt +8 -3
- package/src/core/src/tools/builtin/terminal.txt +1 -1
- package/src/core/src/tools/builtin/todos.txt +44 -4
- package/src/prompts/src/agents/build.txt +23 -211
- package/src/prompts/src/base.txt +33 -32
- package/src/prompts/src/providers/anthropic.txt +58 -210
- package/src/prompts/src/providers/default.txt +36 -472
- package/src/prompts/src/providers/glm.txt +43 -342
- package/src/prompts/src/providers/google.txt +55 -178
- package/src/prompts/src/providers/moonshot.txt +43 -396
- package/src/prompts/src/providers/openai.txt +95 -359
- package/src/providers/src/catalog.ts +67 -39
- package/src/skills/parser.ts +10 -4
- package/src/skills/tool.ts +91 -13
|
@@ -29,32 +29,6 @@ export const catalog: Partial<Record<ProviderId, ProviderCatalogEntry>> = {
|
|
|
29
29
|
output: 0,
|
|
30
30
|
},
|
|
31
31
|
},
|
|
32
|
-
{
|
|
33
|
-
id: 'codex-mini-latest',
|
|
34
|
-
ownedBy: 'openai',
|
|
35
|
-
label: 'Codex Mini',
|
|
36
|
-
modalities: {
|
|
37
|
-
input: ['text'],
|
|
38
|
-
output: ['text'],
|
|
39
|
-
},
|
|
40
|
-
toolCall: true,
|
|
41
|
-
reasoningText: true,
|
|
42
|
-
attachment: true,
|
|
43
|
-
temperature: false,
|
|
44
|
-
knowledge: '2024-04',
|
|
45
|
-
releaseDate: '2025-05-16',
|
|
46
|
-
lastUpdated: '2025-05-16',
|
|
47
|
-
openWeights: false,
|
|
48
|
-
cost: {
|
|
49
|
-
input: 1.5,
|
|
50
|
-
output: 6,
|
|
51
|
-
cacheRead: 0.375,
|
|
52
|
-
},
|
|
53
|
-
limit: {
|
|
54
|
-
context: 200000,
|
|
55
|
-
output: 100000,
|
|
56
|
-
},
|
|
57
|
-
},
|
|
58
32
|
{
|
|
59
33
|
id: 'gpt-3.5-turbo',
|
|
60
34
|
ownedBy: 'openai',
|
|
@@ -1752,7 +1726,7 @@ export const catalog: Partial<Record<ProviderId, ProviderCatalogEntry>> = {
|
|
|
1752
1726
|
reasoningText: true,
|
|
1753
1727
|
attachment: true,
|
|
1754
1728
|
temperature: true,
|
|
1755
|
-
knowledge: '2025-05',
|
|
1729
|
+
knowledge: '2025-05-31',
|
|
1756
1730
|
releaseDate: '2026-02-05',
|
|
1757
1731
|
lastUpdated: '2026-03-13',
|
|
1758
1732
|
openWeights: false,
|
|
@@ -1778,8 +1752,8 @@ export const catalog: Partial<Record<ProviderId, ProviderCatalogEntry>> = {
|
|
|
1778
1752
|
toolCall: true,
|
|
1779
1753
|
reasoningText: true,
|
|
1780
1754
|
attachment: true,
|
|
1781
|
-
temperature:
|
|
1782
|
-
knowledge: '2026-01',
|
|
1755
|
+
temperature: false,
|
|
1756
|
+
knowledge: '2026-01-31',
|
|
1783
1757
|
releaseDate: '2026-04-16',
|
|
1784
1758
|
lastUpdated: '2026-04-16',
|
|
1785
1759
|
openWeights: false,
|
|
@@ -1914,7 +1888,7 @@ export const catalog: Partial<Record<ProviderId, ProviderCatalogEntry>> = {
|
|
|
1914
1888
|
reasoningText: true,
|
|
1915
1889
|
attachment: true,
|
|
1916
1890
|
temperature: true,
|
|
1917
|
-
knowledge: '2025-08',
|
|
1891
|
+
knowledge: '2025-08-31',
|
|
1918
1892
|
releaseDate: '2026-02-17',
|
|
1919
1893
|
lastUpdated: '2026-03-13',
|
|
1920
1894
|
openWeights: false,
|
|
@@ -2345,7 +2319,7 @@ export const catalog: Partial<Record<ProviderId, ProviderCatalogEntry>> = {
|
|
|
2345
2319
|
cost: {
|
|
2346
2320
|
input: 1.25,
|
|
2347
2321
|
output: 10,
|
|
2348
|
-
cacheRead: 0.
|
|
2322
|
+
cacheRead: 0.125,
|
|
2349
2323
|
},
|
|
2350
2324
|
limit: {
|
|
2351
2325
|
context: 1048576,
|
|
@@ -3060,7 +3034,7 @@ export const catalog: Partial<Record<ProviderId, ProviderCatalogEntry>> = {
|
|
|
3060
3034
|
reasoningText: true,
|
|
3061
3035
|
attachment: true,
|
|
3062
3036
|
temperature: true,
|
|
3063
|
-
knowledge: '2025-05-
|
|
3037
|
+
knowledge: '2025-05-31',
|
|
3064
3038
|
releaseDate: '2026-02-05',
|
|
3065
3039
|
lastUpdated: '2026-02-05',
|
|
3066
3040
|
openWeights: false,
|
|
@@ -3075,6 +3049,33 @@ export const catalog: Partial<Record<ProviderId, ProviderCatalogEntry>> = {
|
|
|
3075
3049
|
output: 128000,
|
|
3076
3050
|
},
|
|
3077
3051
|
},
|
|
3052
|
+
{
|
|
3053
|
+
id: 'anthropic/claude-opus-4.7',
|
|
3054
|
+
ownedBy: 'anthropic',
|
|
3055
|
+
label: 'Claude Opus 4.7',
|
|
3056
|
+
modalities: {
|
|
3057
|
+
input: ['text', 'image', 'pdf'],
|
|
3058
|
+
output: ['text'],
|
|
3059
|
+
},
|
|
3060
|
+
toolCall: true,
|
|
3061
|
+
reasoningText: true,
|
|
3062
|
+
attachment: true,
|
|
3063
|
+
temperature: false,
|
|
3064
|
+
knowledge: '2026-01-31',
|
|
3065
|
+
releaseDate: '2026-04-16',
|
|
3066
|
+
lastUpdated: '2026-04-16',
|
|
3067
|
+
openWeights: false,
|
|
3068
|
+
cost: {
|
|
3069
|
+
input: 5,
|
|
3070
|
+
output: 25,
|
|
3071
|
+
cacheRead: 0.5,
|
|
3072
|
+
cacheWrite: 6.25,
|
|
3073
|
+
},
|
|
3074
|
+
limit: {
|
|
3075
|
+
context: 1000000,
|
|
3076
|
+
output: 128000,
|
|
3077
|
+
},
|
|
3078
|
+
},
|
|
3078
3079
|
{
|
|
3079
3080
|
id: 'anthropic/claude-sonnet-4',
|
|
3080
3081
|
ownedBy: 'anthropic',
|
|
@@ -3141,6 +3142,7 @@ export const catalog: Partial<Record<ProviderId, ProviderCatalogEntry>> = {
|
|
|
3141
3142
|
reasoningText: true,
|
|
3142
3143
|
attachment: true,
|
|
3143
3144
|
temperature: true,
|
|
3145
|
+
knowledge: '2025-08-31',
|
|
3144
3146
|
releaseDate: '2026-02-17',
|
|
3145
3147
|
lastUpdated: '2026-02-17',
|
|
3146
3148
|
openWeights: false,
|
|
@@ -3687,7 +3689,7 @@ export const catalog: Partial<Record<ProviderId, ProviderCatalogEntry>> = {
|
|
|
3687
3689
|
cost: {
|
|
3688
3690
|
input: 1.25,
|
|
3689
3691
|
output: 10,
|
|
3690
|
-
cacheRead: 0.
|
|
3692
|
+
cacheRead: 0.125,
|
|
3691
3693
|
},
|
|
3692
3694
|
limit: {
|
|
3693
3695
|
context: 1048576,
|
|
@@ -7296,9 +7298,9 @@ export const catalog: Partial<Record<ProviderId, ProviderCatalogEntry>> = {
|
|
|
7296
7298
|
reasoningText: true,
|
|
7297
7299
|
attachment: true,
|
|
7298
7300
|
temperature: true,
|
|
7299
|
-
knowledge: '2025-
|
|
7301
|
+
knowledge: '2025-05-31',
|
|
7300
7302
|
releaseDate: '2026-02-05',
|
|
7301
|
-
lastUpdated: '2026-
|
|
7303
|
+
lastUpdated: '2026-03-13',
|
|
7302
7304
|
openWeights: false,
|
|
7303
7305
|
cost: {
|
|
7304
7306
|
input: 5,
|
|
@@ -7325,8 +7327,8 @@ export const catalog: Partial<Record<ProviderId, ProviderCatalogEntry>> = {
|
|
|
7325
7327
|
toolCall: true,
|
|
7326
7328
|
reasoningText: true,
|
|
7327
7329
|
attachment: true,
|
|
7328
|
-
temperature:
|
|
7329
|
-
knowledge: '2026-01',
|
|
7330
|
+
temperature: false,
|
|
7331
|
+
knowledge: '2026-01-31',
|
|
7330
7332
|
releaseDate: '2026-04-16',
|
|
7331
7333
|
lastUpdated: '2026-04-16',
|
|
7332
7334
|
openWeights: false,
|
|
@@ -7416,7 +7418,7 @@ export const catalog: Partial<Record<ProviderId, ProviderCatalogEntry>> = {
|
|
|
7416
7418
|
reasoningText: true,
|
|
7417
7419
|
attachment: true,
|
|
7418
7420
|
temperature: true,
|
|
7419
|
-
knowledge: '2025-
|
|
7421
|
+
knowledge: '2025-08-31',
|
|
7420
7422
|
releaseDate: '2026-02-17',
|
|
7421
7423
|
lastUpdated: '2026-02-17',
|
|
7422
7424
|
openWeights: false,
|
|
@@ -9689,7 +9691,7 @@ export const catalog: Partial<Record<ProviderId, ProviderCatalogEntry>> = {
|
|
|
9689
9691
|
reasoningText: true,
|
|
9690
9692
|
attachment: true,
|
|
9691
9693
|
temperature: true,
|
|
9692
|
-
knowledge: '2025-
|
|
9694
|
+
knowledge: '2025-05-31',
|
|
9693
9695
|
releaseDate: '2026-02-05',
|
|
9694
9696
|
lastUpdated: '2026-02-05',
|
|
9695
9697
|
openWeights: false,
|
|
@@ -9702,6 +9704,31 @@ export const catalog: Partial<Record<ProviderId, ProviderCatalogEntry>> = {
|
|
|
9702
9704
|
output: 64000,
|
|
9703
9705
|
},
|
|
9704
9706
|
},
|
|
9707
|
+
{
|
|
9708
|
+
id: 'claude-opus-4.7',
|
|
9709
|
+
ownedBy: 'anthropic',
|
|
9710
|
+
label: 'Claude Opus 4.7',
|
|
9711
|
+
modalities: {
|
|
9712
|
+
input: ['text', 'image'],
|
|
9713
|
+
output: ['text'],
|
|
9714
|
+
},
|
|
9715
|
+
toolCall: true,
|
|
9716
|
+
reasoningText: true,
|
|
9717
|
+
attachment: true,
|
|
9718
|
+
temperature: false,
|
|
9719
|
+
knowledge: '2026-01-31',
|
|
9720
|
+
releaseDate: '2026-04-16',
|
|
9721
|
+
lastUpdated: '2026-04-16',
|
|
9722
|
+
openWeights: false,
|
|
9723
|
+
cost: {
|
|
9724
|
+
input: 0,
|
|
9725
|
+
output: 0,
|
|
9726
|
+
},
|
|
9727
|
+
limit: {
|
|
9728
|
+
context: 144000,
|
|
9729
|
+
output: 64000,
|
|
9730
|
+
},
|
|
9731
|
+
},
|
|
9705
9732
|
{
|
|
9706
9733
|
id: 'claude-opus-41',
|
|
9707
9734
|
ownedBy: 'anthropic',
|
|
@@ -9789,6 +9816,7 @@ export const catalog: Partial<Record<ProviderId, ProviderCatalogEntry>> = {
|
|
|
9789
9816
|
reasoningText: true,
|
|
9790
9817
|
attachment: true,
|
|
9791
9818
|
temperature: true,
|
|
9819
|
+
knowledge: '2025-08-31',
|
|
9792
9820
|
releaseDate: '2026-02-17',
|
|
9793
9821
|
lastUpdated: '2026-02-17',
|
|
9794
9822
|
openWeights: false,
|
package/src/skills/parser.ts
CHANGED
|
@@ -60,12 +60,16 @@ function parseYamlFrontmatter(
|
|
|
60
60
|
const key = normalizeKey(trimmed.slice(0, colonIdx).trim());
|
|
61
61
|
const value = trimmed.slice(colonIdx + 1).trim();
|
|
62
62
|
|
|
63
|
-
|
|
63
|
+
// Handle YAML block scalars with optional chomping/indentation indicators:
|
|
64
|
+
// `|`, `>`, `|-`, `>-`, `|+`, `>+`, `|2`, `>2-`, etc.
|
|
65
|
+
const blockScalarMatch = value.match(/^([|>])[-+]?\d*[-+]?$/);
|
|
66
|
+
if (blockScalarMatch) {
|
|
67
|
+
const style = blockScalarMatch[1] as '|' | '>';
|
|
64
68
|
const { content, nextIndex } = readBlockScalar(
|
|
65
69
|
lines,
|
|
66
70
|
index + 1,
|
|
67
71
|
indent,
|
|
68
|
-
|
|
72
|
+
style,
|
|
69
73
|
);
|
|
70
74
|
result[key] = content;
|
|
71
75
|
index = nextIndex;
|
|
@@ -142,8 +146,10 @@ function readNestedObject(
|
|
|
142
146
|
const key = normalizeKey(trimmed.slice(0, colonIdx).trim());
|
|
143
147
|
const value = trimmed.slice(colonIdx + 1).trim();
|
|
144
148
|
|
|
145
|
-
|
|
146
|
-
|
|
149
|
+
const blockScalarMatch = value.match(/^([|>])[-+]?\d*[-+]?$/);
|
|
150
|
+
if (blockScalarMatch) {
|
|
151
|
+
const style = blockScalarMatch[1] as '|' | '>';
|
|
152
|
+
const block = readBlockScalar(lines, index + 1, indent, style);
|
|
147
153
|
result[key] = block.content;
|
|
148
154
|
index = block.nextIndex;
|
|
149
155
|
continue;
|
package/src/skills/tool.ts
CHANGED
|
@@ -120,32 +120,53 @@ async function loadSubFile(
|
|
|
120
120
|
|
|
121
121
|
function buildSkillDescription(): string {
|
|
122
122
|
if (cachedSkillList.length === 0) {
|
|
123
|
-
return 'Load a skill by name. No skills are currently available.';
|
|
123
|
+
return 'Load a skill by name to get detailed, task-specific instructions. No skills are currently available.';
|
|
124
124
|
}
|
|
125
125
|
|
|
126
|
-
|
|
126
|
+
// Dedupe by name — later scopes (cwd > repo > user) have already overwritten
|
|
127
|
+
// earlier ones in the loader, so the cached list is deduplicated. We re-dedupe
|
|
128
|
+
// defensively here in case the same name slipped through from different dirs.
|
|
129
|
+
const seen = new Set<string>();
|
|
130
|
+
const unique: DiscoveredSkill[] = [];
|
|
131
|
+
for (const s of cachedSkillList) {
|
|
132
|
+
const key = s.name.trim();
|
|
133
|
+
if (!key || seen.has(key)) continue;
|
|
134
|
+
seen.add(key);
|
|
135
|
+
unique.push(s);
|
|
136
|
+
}
|
|
137
|
+
unique.sort((a, b) => a.name.localeCompare(b.name));
|
|
138
|
+
|
|
139
|
+
const skillsXml = unique
|
|
127
140
|
.map(
|
|
128
141
|
(s) =>
|
|
129
|
-
`<skill><name>${escapeXml(s.name)}</name><description>${escapeXml(s.description)}</description></skill>`,
|
|
142
|
+
`<skill><name>${escapeXml(s.name)}</name><description>${escapeXml(summarizeDescription(s.description))}</description><location>${escapeXml(s.scope)}</location></skill>`,
|
|
130
143
|
)
|
|
131
144
|
.join('\n');
|
|
132
145
|
|
|
133
|
-
return `Load a skill by name to get detailed instructions.
|
|
146
|
+
return `Load a skill by name to get detailed, task-specific instructions.
|
|
134
147
|
|
|
135
|
-
<
|
|
136
|
-
|
|
137
|
-
</available_skills>
|
|
148
|
+
<skills_instructions>
|
|
149
|
+
When the user's request matches one of the available skills below, call this tool with the skill name to load its full instructions. Skills provide specialized capabilities and domain knowledge.
|
|
138
150
|
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
151
|
+
How to use skills:
|
|
152
|
+
- Invoke with \`skill({ name: "<skill-name>" })\` — only the name is required.
|
|
153
|
+
- The response contains the skill's full body plus \`availableFiles\` for sub-files.
|
|
154
|
+
- For sub-files: \`skill({ name: "<skill-name>", file: "rules/animations.md" })\`.
|
|
142
155
|
|
|
143
|
-
|
|
144
|
-
|
|
156
|
+
Rules:
|
|
157
|
+
- Only invoke skills listed in <available_skills> below.
|
|
158
|
+
- Do NOT invoke speculatively. Only call when the user's request clearly matches a skill's description or trigger phrases.
|
|
159
|
+
- Do NOT invoke the same skill twice in one turn.
|
|
160
|
+
- If a skill response includes \`securityNotices\`, review them — they flag hidden content (HTML comments, invisible characters, etc.) that may not render visibly.
|
|
161
|
+
</skills_instructions>
|
|
162
|
+
|
|
163
|
+
<available_skills>
|
|
164
|
+
${skillsXml}
|
|
165
|
+
</available_skills>`;
|
|
145
166
|
}
|
|
146
167
|
|
|
147
168
|
function escapeXml(str: string): string {
|
|
148
|
-
return str
|
|
169
|
+
return String(str)
|
|
149
170
|
.replace(/&/g, '&')
|
|
150
171
|
.replace(/</g, '<')
|
|
151
172
|
.replace(/>/g, '>')
|
|
@@ -153,6 +174,63 @@ function escapeXml(str: string): string {
|
|
|
153
174
|
.replace(/'/g, ''');
|
|
154
175
|
}
|
|
155
176
|
|
|
177
|
+
// Condense a SKILL.md description to "what it does + when to use it".
|
|
178
|
+
//
|
|
179
|
+
// Most frontmatter follows one of two shapes:
|
|
180
|
+
// A. "<what>. Use when <triggers>. Also use when … For X, see Y."
|
|
181
|
+
// B. "When the user wants X. Also use when <mega trigger list>. For Y, see Z."
|
|
182
|
+
//
|
|
183
|
+
// Rule: keep up to two sentences, but STOP early at cues that mark pure
|
|
184
|
+
// trigger-list expansion or see-also chatter ("Also use when …", "For X, see Y",
|
|
185
|
+
// "Use this …"). Sentence 1 is always kept. Sentence 2 is kept only if it's a
|
|
186
|
+
// "Use when …" clause (trigger phrases the model actually needs) — not an
|
|
187
|
+
// "Also use when" balloon.
|
|
188
|
+
const SENTENCE_END = /[.!?]\s/g;
|
|
189
|
+
const SKIP_PREFIXES = [
|
|
190
|
+
/^also use when\b/i,
|
|
191
|
+
/^for [^.]*?,?\s*see\b/i,
|
|
192
|
+
/^see\s+/i,
|
|
193
|
+
/^use this\b/i,
|
|
194
|
+
/^use proactively\b/i,
|
|
195
|
+
/^distinct from\b/i,
|
|
196
|
+
/^different from\b/i,
|
|
197
|
+
/^not for\b/i,
|
|
198
|
+
];
|
|
199
|
+
|
|
200
|
+
function shouldSkipSentence(sentence: string): boolean {
|
|
201
|
+
const s = sentence.trim();
|
|
202
|
+
return SKIP_PREFIXES.some((re) => re.test(s));
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
export function summarizeDescription(raw: string): string {
|
|
206
|
+
const text = String(raw ?? '')
|
|
207
|
+
.replace(/\s+/g, ' ')
|
|
208
|
+
.trim();
|
|
209
|
+
if (!text) return '';
|
|
210
|
+
|
|
211
|
+
// Split into sentences, keeping terminal punctuation.
|
|
212
|
+
const sentences: string[] = [];
|
|
213
|
+
SENTENCE_END.lastIndex = 0;
|
|
214
|
+
let lastIndex = 0;
|
|
215
|
+
let match: RegExpExecArray | null;
|
|
216
|
+
// biome-ignore lint/suspicious/noAssignInExpressions: standard regex iteration
|
|
217
|
+
while ((match = SENTENCE_END.exec(text)) !== null) {
|
|
218
|
+
sentences.push(text.slice(lastIndex, match.index + 1).trim());
|
|
219
|
+
lastIndex = match.index + match[0].length;
|
|
220
|
+
}
|
|
221
|
+
if (lastIndex < text.length) sentences.push(text.slice(lastIndex).trim());
|
|
222
|
+
|
|
223
|
+
if (sentences.length === 0) return text;
|
|
224
|
+
|
|
225
|
+
const kept: string[] = [sentences[0]]; // always keep sentence 1 (what)
|
|
226
|
+
// Keep sentence 2 only if it adds routing signal (e.g. starts with "Use when").
|
|
227
|
+
if (sentences[1] && !shouldSkipSentence(sentences[1])) {
|
|
228
|
+
kept.push(sentences[1]);
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
return kept.join(' ');
|
|
232
|
+
}
|
|
233
|
+
|
|
156
234
|
export function rebuildSkillDescription(): string {
|
|
157
235
|
return buildSkillDescription();
|
|
158
236
|
}
|