synthos 0.10.0 → 0.11.0
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/README.md +5 -5
- package/default-pages/elevenlabs_effects_studio/chat-history.json +1 -0
- package/default-pages/elevenlabs_effects_studio/page.html +1345 -1363
- package/default-pages/elevenlabs_effects_studio/page.json +13 -11
- package/default-pages/elevenlabs_voice_studio/chat-history.json +1 -0
- package/default-pages/elevenlabs_voice_studio/page.html +782 -801
- package/default-pages/elevenlabs_voice_studio/page.json +13 -11
- package/default-pages/json_tools/chat-history.json +1 -0
- package/default-pages/json_tools/page.html +70 -90
- package/default-pages/json_tools/page.json +12 -10
- package/default-pages/my_notes/chat-history.json +1 -0
- package/default-pages/my_notes/page.html +115 -131
- package/default-pages/my_notes/page.json +14 -12
- package/default-pages/neon_asteroids/chat-history.json +1 -0
- package/default-pages/neon_asteroids/page.html +1777 -1803
- package/default-pages/neon_asteroids/page.json +14 -12
- package/default-pages/oregon_trail/chat-history.json +1 -0
- package/default-pages/oregon_trail/page.html +290 -307
- package/default-pages/oregon_trail/page.json +14 -12
- package/default-pages/solar_explorer/chat-history.json +1 -0
- package/default-pages/solar_explorer/page.html +1929 -1951
- package/default-pages/solar_explorer/page.json +14 -12
- package/default-pages/solar_tutorial/chat-history.json +1 -0
- package/default-pages/solar_tutorial/page.html +464 -478
- package/default-pages/solar_tutorial/page.json +12 -10
- package/default-pages/us_map/chat-history.json +1 -0
- package/default-pages/us_map/page.html +170 -193
- package/default-pages/us_map/page.json +14 -12
- package/default-pages/us_map/page.light.png +0 -0
- package/default-pages/us_map_1850/chat-history.json +1 -0
- package/default-pages/us_map_1850/page.html +302 -326
- package/default-pages/us_map_1850/page.json +14 -12
- package/default-pages/western_cities_1850/chat-history.json +1 -0
- package/default-pages/western_cities_1850/page.html +503 -527
- package/default-pages/western_cities_1850/page.json +14 -12
- package/default-themes/aurora-dawn.v3.css +15 -14
- package/default-themes/aurora-dusk.v3.css +26 -26
- package/default-themes/cosmos-dawn.v3.css +15 -14
- package/default-themes/cosmos-dusk.v3.css +26 -26
- package/default-themes/elemental-dawn.v3.css +200 -0
- package/default-themes/nebula-dawn.v3.css +15 -14
- package/default-themes/nebula-dusk.v3.css +24 -24
- package/default-themes/solar-flare-dawn.v3.css +15 -14
- package/default-themes/solar-flare-dusk.v3.css +26 -26
- package/dist/builders/anthropic.d.ts +26 -2
- package/dist/builders/anthropic.d.ts.map +1 -1
- package/dist/builders/anthropic.js +132 -31
- package/dist/builders/anthropic.js.map +1 -1
- package/dist/builders/claudecode.d.ts +13 -0
- package/dist/builders/claudecode.d.ts.map +1 -0
- package/dist/builders/claudecode.js +253 -0
- package/dist/builders/claudecode.js.map +1 -0
- package/dist/builders/index.d.ts +2 -1
- package/dist/builders/index.d.ts.map +1 -1
- package/dist/builders/index.js +8 -1
- package/dist/builders/index.js.map +1 -1
- package/dist/builders/openai.js +2 -1
- package/dist/builders/openai.js.map +1 -1
- package/dist/builders/types.d.ts +31 -7
- package/dist/builders/types.d.ts.map +1 -1
- package/dist/builders/types.js +60 -28
- package/dist/builders/types.js.map +1 -1
- package/dist/connectors/types.d.ts +8 -0
- package/dist/connectors/types.d.ts.map +1 -1
- package/dist/init.d.ts.map +1 -1
- package/dist/init.js +13 -6
- package/dist/init.js.map +1 -1
- package/dist/migrations.d.ts.map +1 -1
- package/dist/migrations.js +161 -14
- package/dist/migrations.js.map +1 -1
- package/dist/models/anthropic.d.ts +1 -0
- package/dist/models/anthropic.d.ts.map +1 -1
- package/dist/models/anthropic.js +129 -29
- package/dist/models/anthropic.js.map +1 -1
- package/dist/models/chainOfThought.d.ts.map +1 -1
- package/dist/models/chainOfThought.js +32 -19
- package/dist/models/chainOfThought.js.map +1 -1
- package/dist/models/index.d.ts +2 -2
- package/dist/models/index.d.ts.map +1 -1
- package/dist/models/index.js +2 -1
- package/dist/models/index.js.map +1 -1
- package/dist/models/providers.d.ts +1 -0
- package/dist/models/providers.d.ts.map +1 -1
- package/dist/models/providers.js +12 -4
- package/dist/models/providers.js.map +1 -1
- package/dist/models/types.d.ts +15 -1
- package/dist/models/types.d.ts.map +1 -1
- package/dist/models/types.js.map +1 -1
- package/dist/pages.d.ts +57 -8
- package/dist/pages.d.ts.map +1 -1
- package/dist/pages.js +258 -45
- package/dist/pages.js.map +1 -1
- package/dist/service/createCompletePrompt.d.ts.map +1 -1
- package/dist/service/createCompletePrompt.js +5 -0
- package/dist/service/createCompletePrompt.js.map +1 -1
- package/dist/service/mediaCache.d.ts +36 -0
- package/dist/service/mediaCache.d.ts.map +1 -0
- package/dist/service/mediaCache.js +182 -0
- package/dist/service/mediaCache.js.map +1 -0
- package/dist/service/pageValidator.d.ts +25 -0
- package/dist/service/pageValidator.d.ts.map +1 -0
- package/dist/service/pageValidator.js +315 -0
- package/dist/service/pageValidator.js.map +1 -0
- package/dist/service/server.d.ts.map +1 -1
- package/dist/service/server.js +4 -0
- package/dist/service/server.js.map +1 -1
- package/dist/service/sharedTableSchema.d.ts +73 -0
- package/dist/service/sharedTableSchema.d.ts.map +1 -0
- package/dist/service/sharedTableSchema.js +206 -0
- package/dist/service/sharedTableSchema.js.map +1 -0
- package/dist/service/transformPage.d.ts +49 -11
- package/dist/service/transformPage.d.ts.map +1 -1
- package/dist/service/transformPage.js +354 -241
- package/dist/service/transformPage.js.map +1 -1
- package/dist/service/useApiRoutes.d.ts.map +1 -1
- package/dist/service/useApiRoutes.js +288 -34
- package/dist/service/useApiRoutes.js.map +1 -1
- package/dist/service/useConnectorRoutes.d.ts.map +1 -1
- package/dist/service/useConnectorRoutes.js +170 -32
- package/dist/service/useConnectorRoutes.js.map +1 -1
- package/dist/service/useDataRoutes.d.ts.map +1 -1
- package/dist/service/useDataRoutes.js +59 -2
- package/dist/service/useDataRoutes.js.map +1 -1
- package/dist/service/useExtractRoutes.d.ts +4 -0
- package/dist/service/useExtractRoutes.d.ts.map +1 -0
- package/dist/service/useExtractRoutes.js +304 -0
- package/dist/service/useExtractRoutes.js.map +1 -0
- package/dist/service/usePageRoutes.d.ts +17 -0
- package/dist/service/usePageRoutes.d.ts.map +1 -1
- package/dist/service/usePageRoutes.js +1385 -483
- package/dist/service/usePageRoutes.js.map +1 -1
- package/dist/service/useSharedDataRoutes.d.ts.map +1 -1
- package/dist/service/useSharedDataRoutes.js +54 -2
- package/dist/service/useSharedDataRoutes.js.map +1 -1
- package/dist/settings.d.ts +27 -0
- package/dist/settings.d.ts.map +1 -1
- package/dist/settings.js +40 -1
- package/dist/settings.js.map +1 -1
- package/dist/themes.d.ts +0 -5
- package/dist/themes.d.ts.map +1 -1
- package/dist/themes.js +3 -95
- package/dist/themes.js.map +1 -1
- package/migration-rules/v2-to-v3.md +277 -119
- package/package.json +5 -1
- package/{default-pages/application → required-pages/_shell}/page.html +56 -42
- package/required-pages/_shell/page.json +14 -0
- package/required-pages/_starters/page.html +534 -0
- package/required-pages/_starters/page.json +12 -0
- package/required-pages/builder/page.html +353 -43
- package/required-pages/builder/page.json +12 -10
- package/required-pages/pages/page.html +697 -924
- package/required-pages/pages/page.json +12 -10
- package/required-pages/settings/page.html +1879 -1753
- package/required-pages/settings/page.json +12 -10
- package/required-pages/synthos_apis/page.html +834 -845
- package/required-pages/synthos_apis/page.json +12 -10
- package/required-pages/synthos_scripts/page.html +74 -88
- package/required-pages/synthos_scripts/page.json +12 -10
- package/scripts/append-instructions.py +90 -0
- package/scripts/audit-instructions.py +76 -0
- package/scripts/cleanup-shell-markup.mjs +112 -0
- package/service-connectors/buffer/connector.json +46 -0
- package/service-connectors/canva/connector.json +67 -0
- package/service-connectors/elevenlabs/connector.json +1 -1
- package/src/builders/anthropic.ts +155 -30
- package/src/builders/claudecode.ts +310 -0
- package/src/builders/index.ts +7 -1
- package/src/builders/openai.ts +2 -1
- package/src/builders/types.ts +93 -32
- package/src/connectors/types.ts +8 -0
- package/src/init.ts +13 -7
- package/src/migrations.ts +187 -16
- package/src/models/anthropic.ts +140 -30
- package/src/models/chainOfThought.ts +33 -18
- package/src/models/index.ts +2 -2
- package/src/models/providers.ts +12 -3
- package/src/models/types.ts +21 -1
- package/src/pages.ts +271 -35
- package/src/service/createCompletePrompt.ts +6 -0
- package/src/service/mediaCache.ts +206 -0
- package/src/service/pageValidator.ts +337 -0
- package/src/service/server.ts +4 -0
- package/src/service/sharedTableSchema.ts +236 -0
- package/src/service/transformPage.ts +370 -260
- package/src/service/useApiRoutes.ts +282 -32
- package/src/service/useConnectorRoutes.ts +189 -34
- package/src/service/useDataRoutes.ts +198 -116
- package/src/service/useExtractRoutes.ts +331 -0
- package/src/service/usePageRoutes.ts +1411 -394
- package/src/service/useSharedDataRoutes.ts +184 -109
- package/src/settings.ts +65 -0
- package/src/themes.ts +78 -180
- package/starters/blank_starter/chat-history.json +1 -0
- package/starters/blank_starter/page.dark.png +0 -0
- package/starters/blank_starter/page.html +47 -0
- package/starters/blank_starter/page.json +13 -0
- package/starters/blank_starter/page.light.png +0 -0
- package/starters/calculator_starter/chat-history.json +1 -0
- package/starters/calculator_starter/page.dark.png +0 -0
- package/starters/calculator_starter/page.html +232 -0
- package/starters/calculator_starter/page.json +13 -0
- package/starters/calculator_starter/page.light.png +0 -0
- package/starters/calendar_starter/chat-history.json +1 -0
- package/starters/calendar_starter/page.dark.png +0 -0
- package/starters/calendar_starter/page.html +495 -0
- package/starters/calendar_starter/page.json +13 -0
- package/starters/calendar_starter/page.light.png +0 -0
- package/starters/chat_starter/chat-history.json +1 -0
- package/starters/chat_starter/page.dark.png +0 -0
- package/starters/chat_starter/page.html +351 -0
- package/starters/chat_starter/page.json +13 -0
- package/starters/chat_starter/page.light.png +0 -0
- package/starters/checklist_starter/chat-history.json +1 -0
- package/starters/checklist_starter/page.dark.png +0 -0
- package/starters/checklist_starter/page.html +437 -0
- package/starters/checklist_starter/page.json +13 -0
- package/starters/checklist_starter/page.light.png +0 -0
- package/starters/dashboard_starter/chat-history.json +1 -0
- package/starters/dashboard_starter/page.dark.png +0 -0
- package/starters/dashboard_starter/page.html +195 -0
- package/starters/dashboard_starter/page.json +13 -0
- package/starters/dashboard_starter/page.light.png +0 -0
- package/starters/form_starter/chat-history.json +1 -0
- package/starters/form_starter/page.dark.png +0 -0
- package/starters/form_starter/page.html +313 -0
- package/starters/form_starter/page.json +13 -0
- package/starters/form_starter/page.light.png +0 -0
- package/starters/gallery_starter/chat-history.json +1 -0
- package/starters/gallery_starter/page.dark.png +0 -0
- package/starters/gallery_starter/page.html +418 -0
- package/starters/gallery_starter/page.json +13 -0
- package/starters/gallery_starter/page.light.png +0 -0
- package/starters/generator_starter/chat-history.json +1 -0
- package/starters/generator_starter/page.dark.png +0 -0
- package/starters/generator_starter/page.html +261 -0
- package/starters/generator_starter/page.json +13 -0
- package/starters/generator_starter/page.light.png +0 -0
- package/starters/index.html +538 -0
- package/starters/kanban_starter/chat-history.json +1 -0
- package/starters/kanban_starter/page.dark.png +0 -0
- package/starters/kanban_starter/page.html +432 -0
- package/starters/kanban_starter/page.json +13 -0
- package/starters/kanban_starter/page.light.png +0 -0
- package/starters/presentation_builder/chat-history.json +1 -0
- package/starters/presentation_builder/page.dark.png +0 -0
- package/starters/presentation_builder/page.html +970 -0
- package/starters/presentation_builder/page.json +15 -0
- package/starters/presentation_builder/page.light.png +0 -0
- package/starters/presentation_builder/presentation_voice/voice_config.json +9 -0
- package/starters/pulse_starter/chat-history.json +1 -0
- package/starters/pulse_starter/page.dark.png +0 -0
- package/starters/pulse_starter/page.html +698 -0
- package/starters/pulse_starter/page.json +13 -0
- package/starters/pulse_starter/page.light.png +0 -0
- package/starters/quiz_starter/chat-history.json +1 -0
- package/starters/quiz_starter/page.dark.png +0 -0
- package/starters/quiz_starter/page.html +292 -0
- package/starters/quiz_starter/page.json +13 -0
- package/starters/quiz_starter/page.light.png +0 -0
- package/starters/reference_starter/chat-history.json +1 -0
- package/starters/reference_starter/page.dark.png +0 -0
- package/starters/reference_starter/page.html +250 -0
- package/starters/reference_starter/page.json +13 -0
- package/starters/reference_starter/page.light.png +0 -0
- package/starters/retro_game_starter/chat-history.json +1 -0
- package/starters/retro_game_starter/page.dark.png +0 -0
- package/{default-pages → starters}/retro_game_starter/page.html +1281 -1308
- package/starters/retro_game_starter/page.json +15 -0
- package/starters/retro_game_starter/page.light.png +0 -0
- package/starters/roster_starter/chat-history.json +1 -0
- package/starters/roster_starter/page.dark.png +0 -0
- package/starters/roster_starter/page.html +600 -0
- package/starters/roster_starter/page.json +13 -0
- package/starters/roster_starter/page.light.png +0 -0
- package/starters/server.js +182 -0
- package/starters/start.cmd +1 -0
- package/starters/timeline_starter/chat-history.json +1 -0
- package/starters/timeline_starter/page.dark.png +0 -0
- package/starters/timeline_starter/page.html +446 -0
- package/starters/timeline_starter/page.json +13 -0
- package/starters/timeline_starter/page.light.png +0 -0
- package/starters/tutorial_starter/chat-history.json +1 -0
- package/starters/tutorial_starter/page.dark.png +0 -0
- package/starters/tutorial_starter/page.html +283 -0
- package/starters/tutorial_starter/page.json +13 -0
- package/starters/tutorial_starter/page.light.png +0 -0
- package/static-files/agent.v3.js +122 -0
- package/static-files/connector.v3.js +48 -0
- package/static-files/extract.v3.js +188 -0
- package/static-files/helpers.v3.js +50 -6
- package/static-files/page-bridge.js +114 -0
- package/static-files/page.v3.js +1292 -1290
- package/static-files/script.v3.js +32 -0
- package/static-files/server.v3.js +89 -0
- package/static-files/shell-bridge.v3.js +174 -0
- package/static-files/shell-modals.v3.js +521 -0
- package/static-files/{shell.css → shell.v3.css} +271 -22
- package/static-files/shell.v3.js +1865 -0
- package/static-files/storage.v3.js +176 -0
- package/tests/anthropic.spec.ts +42 -7
- package/tests/builders.spec.ts +72 -4
- package/tests/pageValidator.spec.ts +548 -0
- package/tests/profiles.spec.ts +122 -0
- package/tests/providers.spec.ts +1 -1
- package/tests/sharedTableSchema.spec.ts +242 -0
- package/tests/transformPage.spec.ts +62 -81
- package/default-pages/application/page.json +0 -10
- package/default-pages/retro_game_starter/page.json +0 -12
- package/default-pages/sidebar_page/page.html +0 -51
- package/default-pages/sidebar_page/page.json +0 -10
- package/default-pages/two-panel_page/page.html +0 -68
- package/default-pages/two-panel_page/page.json +0 -10
package/src/migrations.ts
CHANGED
|
@@ -119,31 +119,202 @@ async function migrateV1toV2(html: string, completePrompt: completePrompt): Prom
|
|
|
119
119
|
return migrated;
|
|
120
120
|
}
|
|
121
121
|
|
|
122
|
+
/**
|
|
123
|
+
* v2-compat CSS block — injected into the <head> of every page migrated from v2
|
|
124
|
+
* to v3. Maps the legacy v2 CSS tokens (`--bg-*`, `--accent-*`, `--text-*`,
|
|
125
|
+
* `--border-color`) onto the active v3 theme's semantic tokens (`--bodyBackground`,
|
|
126
|
+
* `--themePrimary`, etc.), so a migrated page inherits whatever v3 theme is
|
|
127
|
+
* active instead of being frozen on the old nebula-dusk palette. Layout-only
|
|
128
|
+
* constants (`--header-*`) stay as literal values.
|
|
129
|
+
*
|
|
130
|
+
* Dropped from the previous compat block: baked `body`, `.viewer-panel`,
|
|
131
|
+
* `.viewer-panel::before`, `@keyframes nebula-pulse`, and `::-webkit-scrollbar*`
|
|
132
|
+
* rules. Those contained hardcoded purple/blue rgba values that looked wrong
|
|
133
|
+
* under non-nebula v3 themes (aurora, cosmos, solar-flare, high-contrast).
|
|
134
|
+
* The shell injects the iframe viewport height chain separately, and
|
|
135
|
+
* FluentLM's base CSS covers global resets.
|
|
136
|
+
*
|
|
137
|
+
* Keep in sync with `migration-rules/v2-to-v3.md` §3.
|
|
138
|
+
*/
|
|
139
|
+
const V2_COMPAT_STYLE = `<style id="v2-compat">
|
|
140
|
+
/* --- v2 → v3 token aliases ---
|
|
141
|
+
Each legacy v2 var resolves to a v3 SEMANTIC token (role-based) so the page
|
|
142
|
+
re-themes automatically between light and dark variants. Do NOT use palette
|
|
143
|
+
tokens (--neutralDark, --neutralPrimaryAlt, etc.) here — those encode a
|
|
144
|
+
FIXED color value and stay dark under light themes, producing hard-coded
|
|
145
|
+
black backgrounds on v2 pages.
|
|
146
|
+
|
|
147
|
+
Component-surface tokens use --defaultStateBackground / --defaultHoverBackground
|
|
148
|
+
(the v3 tokens v3 pages use for card/panel surfaces) instead of the
|
|
149
|
+
body*Background tokens. Every alias has a hex fallback so the compat block
|
|
150
|
+
still produces sensible light defaults even if the theme CSS fails to load
|
|
151
|
+
or a token isn't defined (otherwise the chain resolves to 'initial' and
|
|
152
|
+
backgrounds go transparent). Header geometry stays literal because it's
|
|
153
|
+
layout, not color. */
|
|
154
|
+
:root {
|
|
155
|
+
--bg-primary: var(--bodyBackground, #ffffff);
|
|
156
|
+
--bg-secondary: var(--defaultStateBackground, #faf9f8);
|
|
157
|
+
--bg-tertiary: var(--bodyBackgroundHovered, #f3f2f1);
|
|
158
|
+
|
|
159
|
+
--accent-primary: var(--themePrimary, #0078d4);
|
|
160
|
+
--accent-secondary: var(--themeDarkAlt, #106ebe);
|
|
161
|
+
--accent-tertiary: var(--themeSecondary, #2b88d8);
|
|
162
|
+
--accent-glow: rgba(0,0,0,0.3);
|
|
163
|
+
|
|
164
|
+
--text-primary: var(--bodyText, #333333);
|
|
165
|
+
--text-secondary: var(--bodySubtext, #605e5c);
|
|
166
|
+
|
|
167
|
+
--border-color: var(--bodyDivider, #edebe9);
|
|
168
|
+
|
|
169
|
+
--header-min-height: 58px;
|
|
170
|
+
--header-padding-vertical: 14px;
|
|
171
|
+
--header-padding-horizontal: 20px;
|
|
172
|
+
--header-line-height: 1.25;
|
|
173
|
+
}
|
|
174
|
+
</style>`;
|
|
175
|
+
|
|
176
|
+
/**
|
|
177
|
+
* v2 nebula-dusk palette → v3 token map. Each entry's `rgb` triple is the
|
|
178
|
+
* hardcoded RGB that appeared in the v2 theme (and therefore in v2 page CSS
|
|
179
|
+
* that was hand-matched to it). The `token` is the v3 semantic/palette var
|
|
180
|
+
* that best fits the same role — so under light themes (nebula-dawn,
|
|
181
|
+
* aurora-dawn, solar-flare-dawn, high-contrast-light) the color re-themes
|
|
182
|
+
* instead of standing out as a dark purple-blue blob.
|
|
183
|
+
*
|
|
184
|
+
* Keep in sync with `migration-rules/v2-to-v3.md` §3 "Legacy color mapping".
|
|
185
|
+
*
|
|
186
|
+
* `rgba(0,0,0,*)` is intentionally NOT remapped — theme-neutral shadows read
|
|
187
|
+
* fine under both light and dark themes.
|
|
188
|
+
*/
|
|
189
|
+
type LegacyColorRule = { rgb: [number, number, number]; token: string; hex: string };
|
|
190
|
+
const LEGACY_COLOR_RULES: LegacyColorRule[] = [
|
|
191
|
+
// Brand / accent family (v2 purple-blue ramp)
|
|
192
|
+
{ rgb: [102, 126, 234], token: 'var(--themePrimary)', hex: '#667eea' },
|
|
193
|
+
{ rgb: [118, 75, 162], token: 'var(--themeDarkAlt)', hex: '#764ba2' },
|
|
194
|
+
{ rgb: [138, 43, 226], token: 'var(--themeDarker)', hex: '#8a2be2' },
|
|
195
|
+
{ rgb: [ 75, 0, 130], token: 'var(--themeDarker)', hex: '#4b0082' },
|
|
196
|
+
{ rgb: [240, 147, 251], token: 'var(--themeSecondary)', hex: '#f093fb' },
|
|
197
|
+
{ rgb: [183, 148, 246], token: 'var(--themeTertiary)', hex: '#b794f6' },
|
|
198
|
+
// Dark background family (v2 bg-primary/secondary/tertiary) — mapped to
|
|
199
|
+
// SEMANTIC tokens that flip between light and dark themes. Palette tokens
|
|
200
|
+
// would freeze these as dark under light themes (black blobs in dawn mode).
|
|
201
|
+
{ rgb: [ 26, 26, 46], token: 'var(--bodyBackground)', hex: '#1a1a2e' },
|
|
202
|
+
{ rgb: [ 22, 33, 62], token: 'var(--bodyStandoutBackground)', hex: '#16213e' },
|
|
203
|
+
{ rgb: [ 15, 15, 35], token: 'var(--bodyBackgroundHovered)', hex: '#0f0f23' },
|
|
204
|
+
// Status colors (Bootstrap danger/success/warning used pervasively in v2 pages)
|
|
205
|
+
{ rgb: [220, 53, 69], token: 'var(--red)', hex: '#dc3545' },
|
|
206
|
+
{ rgb: [ 40, 167, 69], token: 'var(--green)', hex: '#28a745' },
|
|
207
|
+
{ rgb: [255, 193, 7], token: 'var(--yellow)', hex: '#ffc107' },
|
|
208
|
+
];
|
|
209
|
+
|
|
210
|
+
/**
|
|
211
|
+
* Replace hardcoded v2-era RGB/hex colors in the full HTML (style blocks,
|
|
212
|
+
* inline `style=""` attrs, and JS template literals) with theme-aware v3
|
|
213
|
+
* tokens. Alpha is preserved via `color-mix(in srgb, <token> X%, transparent)`;
|
|
214
|
+
* solid occurrences collapse to `var(--token)` directly. `rgba(0,0,0,*)` is
|
|
215
|
+
* left as-is by design — theme-neutral shadows.
|
|
216
|
+
*
|
|
217
|
+
* The patterns match specific numeric triples and 6-digit hex codes only, so
|
|
218
|
+
* false positives in non-color contexts (IDs, content text, URLs) are
|
|
219
|
+
* negligible. Hex matches are guarded by `(?<![0-9a-fA-F])` / `(?![0-9a-fA-F])`
|
|
220
|
+
* lookarounds to avoid eating neighboring hex digits (e.g. an 8-digit
|
|
221
|
+
* hex-with-alpha like `#667eeaff`).
|
|
222
|
+
*/
|
|
223
|
+
function remapLegacyColors(html: string): string {
|
|
224
|
+
let out = html;
|
|
225
|
+
for (const rule of LEGACY_COLOR_RULES) {
|
|
226
|
+
const [r, g, b] = rule.rgb;
|
|
227
|
+
|
|
228
|
+
// rgba(R,G,B,A) — preserve alpha via color-mix
|
|
229
|
+
const rgbaPattern = new RegExp(
|
|
230
|
+
`rgba\\(\\s*${r}\\s*,\\s*${g}\\s*,\\s*${b}\\s*,\\s*([\\d.]+)\\s*\\)`,
|
|
231
|
+
'gi'
|
|
232
|
+
);
|
|
233
|
+
out = out.replace(rgbaPattern, (_match, alpha) => {
|
|
234
|
+
const a = parseFloat(alpha);
|
|
235
|
+
if (!isFinite(a) || a >= 1) return rule.token;
|
|
236
|
+
const pct = Math.round(a * 1000) / 10; // 1 decimal
|
|
237
|
+
return `color-mix(in srgb, ${rule.token} ${pct}%, transparent)`;
|
|
238
|
+
});
|
|
239
|
+
|
|
240
|
+
// rgb(R,G,B) or rgba(R,G,B) without alpha — solid color
|
|
241
|
+
const rgbPattern = new RegExp(
|
|
242
|
+
`rgba?\\(\\s*${r}\\s*,\\s*${g}\\s*,\\s*${b}\\s*\\)`,
|
|
243
|
+
'gi'
|
|
244
|
+
);
|
|
245
|
+
out = out.replace(rgbPattern, rule.token);
|
|
246
|
+
|
|
247
|
+
// Bare 6-digit hex (case-insensitive, guarded to not split 8-digit hex)
|
|
248
|
+
const hexEscaped = rule.hex.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
249
|
+
const hexPattern = new RegExp(`(?<![0-9a-fA-F])${hexEscaped}(?![0-9a-fA-F])`, 'gi');
|
|
250
|
+
out = out.replace(hexPattern, rule.token);
|
|
251
|
+
}
|
|
252
|
+
return out;
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
/**
|
|
256
|
+
* Shell-owned DOM + scripts that shipped inline on every v2 page but belong
|
|
257
|
+
* to the v3 iframe shell. At v3 serve time the shell strips these anyway
|
|
258
|
+
* (see `stripShellMarkup$` in `src/service/usePageRoutes.ts`), but baking
|
|
259
|
+
* the removal into the stored page keeps the on-disk HTML clean and stops
|
|
260
|
+
* validators from flagging orphan references to shell-only IDs
|
|
261
|
+
* (`#defaultGreeting`, `#firstRunGreeting`) once the shell DOM that owned
|
|
262
|
+
* them is gone.
|
|
263
|
+
*
|
|
264
|
+
* Keep in sync with `migration-rules/v2-to-v3.md` §2.
|
|
265
|
+
*/
|
|
266
|
+
const V2_SHELL_SELECTORS = [
|
|
267
|
+
'.chat-panel', // chat header + messages + link-group + chatForm + greetings
|
|
268
|
+
'.chat-toggle', // collapsed-chat toggle button
|
|
269
|
+
'#loadingOverlay', // shell provides this via blueprint overlay
|
|
270
|
+
'script#idle-animation', // top-level hideIdleAnimation / showIdleAnimation (also stubbed at runtime)
|
|
271
|
+
'script#first-run-check', // references #defaultGreeting / #firstRunGreeting in the stripped chat-panel
|
|
272
|
+
'script#page-helpers', // shell re-injects with cache-busted URL
|
|
273
|
+
'script#page-script', // shell re-injects with cache-busted URL
|
|
274
|
+
'script#synthos-error-capture', // shell injects when needed
|
|
275
|
+
];
|
|
276
|
+
|
|
122
277
|
/**
|
|
123
278
|
* v2 -> v3: Cheerio-based migration (no LLM).
|
|
124
|
-
* -
|
|
125
|
-
*
|
|
126
|
-
*
|
|
279
|
+
* - Strips v2 shell chrome (.chat-panel, .chat-toggle, #loadingOverlay) and
|
|
280
|
+
* the inline scripts that only make sense alongside it (idle-animation,
|
|
281
|
+
* first-run-check, legacy page-helpers/page-script).
|
|
282
|
+
* - Injects <style id="v2-compat"> at the top of <head> (aliases legacy v2
|
|
283
|
+
* CSS custom properties to active v3 theme tokens).
|
|
284
|
+
* - Remaps hardcoded v2-palette RGB/hex colors to theme-aware v3 tokens so
|
|
285
|
+
* migrated pages re-theme under light/dark variants instead of freezing
|
|
286
|
+
* on the old nebula-dusk palette.
|
|
127
287
|
*/
|
|
128
288
|
async function migrateV2toV3(html: string, _completePrompt: completePrompt): Promise<string> {
|
|
129
|
-
|
|
289
|
+
// Run postProcessV2 first for its shared-CSS cleanup. Must happen BEFORE
|
|
290
|
+
// the v2-compat injection — postProcessV2 strips :root, *, body, html,
|
|
291
|
+
// .viewer-panel, @keyframes nebula-pulse, and ::-webkit-scrollbar* rules
|
|
292
|
+
// from every <style> block, and the v2-compat block intentionally
|
|
293
|
+
// contains exactly those rules. postProcessV2 also RESTORES missing
|
|
294
|
+
// chat-panel/thoughts/loadingOverlay which we then strip below — accept
|
|
295
|
+
// the transient insertion; the shared-CSS strip is the load-bearing step.
|
|
296
|
+
const out = postProcessV2(html);
|
|
130
297
|
|
|
131
|
-
|
|
132
|
-
$('.link-group').remove();
|
|
298
|
+
const $ = cheerio.load(out, { decodeEntities: false });
|
|
133
299
|
|
|
134
|
-
//
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
);
|
|
300
|
+
// Strip v2 shell chrome + scripts. This supersedes the older
|
|
301
|
+
// link-group/chat-input/chat-submit fixups — all three lived inside
|
|
302
|
+
// .chat-panel, so removing the panel wholesale obsoletes them.
|
|
303
|
+
for (const sel of V2_SHELL_SELECTORS) {
|
|
304
|
+
$(sel).remove();
|
|
140
305
|
}
|
|
141
306
|
|
|
142
|
-
//
|
|
143
|
-
|
|
307
|
+
// Inject v2-compat CSS as the first child of <head>. Idempotent — skip
|
|
308
|
+
// if an existing v2-compat block is already present.
|
|
309
|
+
if ($('style#v2-compat').length === 0) {
|
|
310
|
+
$('head').prepend(V2_COMPAT_STYLE + '\n');
|
|
311
|
+
}
|
|
144
312
|
|
|
145
|
-
//
|
|
146
|
-
|
|
313
|
+
// Remap hardcoded v2-era RGB/hex colors to theme-aware v3 tokens. Runs
|
|
314
|
+
// LAST so the compat block (which uses intentional theme-neutral
|
|
315
|
+
// rgba(0,0,0,0.3) for --accent-glow) is in the output but untouched by
|
|
316
|
+
// the remap (0,0,0 is not in the rule table).
|
|
317
|
+
return remapLegacyColors($.html());
|
|
147
318
|
}
|
|
148
319
|
|
|
149
320
|
/**
|
package/src/models/anthropic.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import Anthropic from '@anthropic-ai/sdk';
|
|
2
|
-
import { AgentCompletion, completePrompt, PromptCompletionArgs, RequestError, isMultimodalContent } from './types';
|
|
2
|
+
import { AgentCompletion, completePrompt, PromptCompletionArgs, RequestError, isMultimodalContent, ToolHandler } from './types';
|
|
3
3
|
|
|
4
4
|
export interface AnthropicArgs {
|
|
5
5
|
apiKey: string;
|
|
@@ -18,6 +18,7 @@ export function buildAnthropicRequest(args: PromptCompletionArgs, defaultTemp: n
|
|
|
18
18
|
system: string | Anthropic.TextBlockParam[] | undefined;
|
|
19
19
|
temperature: number;
|
|
20
20
|
outputConfig?: Anthropic.OutputConfig;
|
|
21
|
+
tools?: Anthropic.Tool[];
|
|
21
22
|
} {
|
|
22
23
|
const reqTemp = args.temperature ?? defaultTemp;
|
|
23
24
|
|
|
@@ -45,14 +46,11 @@ export function buildAnthropicRequest(args: PromptCompletionArgs, defaultTemp: n
|
|
|
45
46
|
userContent = promptContent;
|
|
46
47
|
}
|
|
47
48
|
|
|
48
|
-
//
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
} else {
|
|
54
|
-
messages.push({ role: 'user', content: userContent });
|
|
55
|
-
}
|
|
49
|
+
// Claude 4.6+ rejects assistant-message prefill ("This model does not support
|
|
50
|
+
// assistant message prefill. The conversation must end with a user message.").
|
|
51
|
+
// The chainOfThought parser already extracts JSON via indexOf('{')/lastIndexOf('}'),
|
|
52
|
+
// and the system prompt instructs the model to emit JSON, so no prefill is needed.
|
|
53
|
+
messages.push({ role: 'user', content: userContent });
|
|
56
54
|
|
|
57
55
|
let system = args.system?.content;
|
|
58
56
|
if (args.jsonSchema) {
|
|
@@ -70,7 +68,74 @@ export function buildAnthropicRequest(args: PromptCompletionArgs, defaultTemp: n
|
|
|
70
68
|
? { format: { type: 'json_schema', schema: args.outputSchema } }
|
|
71
69
|
: undefined;
|
|
72
70
|
|
|
73
|
-
|
|
71
|
+
// Tool definitions
|
|
72
|
+
const tools: Anthropic.Tool[] | undefined = args.tools && args.tools.length > 0
|
|
73
|
+
? args.tools.map(t => ({
|
|
74
|
+
name: t.name,
|
|
75
|
+
description: t.description,
|
|
76
|
+
input_schema: t.input_schema as Anthropic.Tool.InputSchema,
|
|
77
|
+
}))
|
|
78
|
+
: undefined;
|
|
79
|
+
|
|
80
|
+
return { messages, system: finalSystem, temperature: reqTemp, outputConfig, tools };
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
interface PendingToolUse {
|
|
84
|
+
id: string;
|
|
85
|
+
name: string;
|
|
86
|
+
partialJson: string;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Stream a single Anthropic request, accumulating text deltas and any tool_use
|
|
91
|
+
* blocks the model emits. Returns both the text buffer and the tool_use blocks
|
|
92
|
+
* (if any) so the caller can decide whether to loop on tool results.
|
|
93
|
+
*/
|
|
94
|
+
async function streamOnce(
|
|
95
|
+
client: Anthropic,
|
|
96
|
+
params: Anthropic.MessageCreateParamsStreaming
|
|
97
|
+
): Promise<{ text: string; toolUses: PendingToolUse[]; stopReason: Anthropic.StopReason | null }> {
|
|
98
|
+
const stream = await client.messages.create(params);
|
|
99
|
+
|
|
100
|
+
// Track content blocks by stream index. Tool_use blocks get their partial_json
|
|
101
|
+
// routed to their own buffer; text + structured-output input_json_deltas go to text.
|
|
102
|
+
const textByIndex = new Map<number, string>();
|
|
103
|
+
const toolByIndex = new Map<number, PendingToolUse>();
|
|
104
|
+
let stopReason: Anthropic.StopReason | null = null;
|
|
105
|
+
|
|
106
|
+
for await (const event of stream) {
|
|
107
|
+
if (event.type === 'content_block_start') {
|
|
108
|
+
const block = event.content_block;
|
|
109
|
+
if (block.type === 'tool_use') {
|
|
110
|
+
toolByIndex.set(event.index, { id: block.id, name: block.name, partialJson: '' });
|
|
111
|
+
} else if (block.type === 'text') {
|
|
112
|
+
textByIndex.set(event.index, '');
|
|
113
|
+
}
|
|
114
|
+
} else if (event.type === 'content_block_delta') {
|
|
115
|
+
if (event.delta.type === 'text_delta') {
|
|
116
|
+
textByIndex.set(event.index, (textByIndex.get(event.index) ?? '') + event.delta.text);
|
|
117
|
+
} else if (event.delta.type === 'input_json_delta') {
|
|
118
|
+
const tool = toolByIndex.get(event.index);
|
|
119
|
+
if (tool) {
|
|
120
|
+
tool.partialJson += event.delta.partial_json;
|
|
121
|
+
} else {
|
|
122
|
+
// Structured output streams JSON as input_json_delta into a text block —
|
|
123
|
+
// accumulate into the text buffer so parseBuilderResponse sees the JSON.
|
|
124
|
+
textByIndex.set(event.index, (textByIndex.get(event.index) ?? '') + event.delta.partial_json);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
} else if (event.type === 'message_delta') {
|
|
128
|
+
if (event.delta.stop_reason) stopReason = event.delta.stop_reason;
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
const text = Array.from(textByIndex.entries())
|
|
133
|
+
.sort(([a], [b]) => a - b)
|
|
134
|
+
.map(([, v]) => v)
|
|
135
|
+
.join('');
|
|
136
|
+
|
|
137
|
+
const toolUses = Array.from(toolByIndex.values());
|
|
138
|
+
return { text, toolUses, stopReason };
|
|
74
139
|
}
|
|
75
140
|
|
|
76
141
|
export function anthropic(args: AnthropicArgs): completePrompt {
|
|
@@ -79,33 +144,78 @@ export function anthropic(args: AnthropicArgs): completePrompt {
|
|
|
79
144
|
const client = new Anthropic({ apiKey, baseURL, maxRetries });
|
|
80
145
|
|
|
81
146
|
return async (completionArgs: PromptCompletionArgs): Promise<AgentCompletion<string>> => {
|
|
82
|
-
const { messages, system: systemContent, temperature: reqTemp, outputConfig } =
|
|
147
|
+
const { messages, system: systemContent, temperature: reqTemp, outputConfig, tools } =
|
|
148
|
+
buildAnthropicRequest(completionArgs, temperature);
|
|
83
149
|
|
|
84
|
-
const
|
|
150
|
+
const hasTools = !!(tools && tools.length > 0);
|
|
151
|
+
const maxIterations = completionArgs.maxToolIterations ?? 3;
|
|
152
|
+
const toolHandlers = completionArgs.toolHandlers ?? {};
|
|
85
153
|
|
|
86
154
|
try {
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
155
|
+
// Mutable copy of messages — extended each tool-use iteration.
|
|
156
|
+
const turnMessages: Anthropic.MessageParam[] = messages as Anthropic.MessageParam[];
|
|
157
|
+
let lastText = '';
|
|
158
|
+
|
|
159
|
+
for (let iteration = 0; iteration < maxIterations; iteration++) {
|
|
160
|
+
const params: Anthropic.MessageCreateParamsStreaming = {
|
|
161
|
+
model,
|
|
162
|
+
max_tokens: 32768,
|
|
163
|
+
temperature: reqTemp,
|
|
164
|
+
system: systemContent,
|
|
165
|
+
messages: turnMessages,
|
|
166
|
+
stream: true,
|
|
167
|
+
...(outputConfig && { output_config: outputConfig }),
|
|
168
|
+
...(hasTools && { tools }),
|
|
169
|
+
};
|
|
170
|
+
|
|
171
|
+
const { text, toolUses, stopReason } = await streamOnce(client, params);
|
|
172
|
+
lastText = text;
|
|
173
|
+
|
|
174
|
+
// Terminal turn: no tool_use blocks OR model stopped for a non-tool reason.
|
|
175
|
+
if (!hasTools || toolUses.length === 0 || stopReason !== 'tool_use') {
|
|
176
|
+
return { completed: true, value: lastText };
|
|
101
177
|
}
|
|
102
|
-
}
|
|
103
178
|
|
|
104
|
-
|
|
105
|
-
|
|
179
|
+
// Tool-use turn: notify, execute handlers in parallel, append results, loop.
|
|
180
|
+
if (completionArgs.onToolCall) {
|
|
181
|
+
completionArgs.onToolCall(toolUses.map(t => t.name));
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
const toolResults: Anthropic.ToolResultBlockParam[] = await Promise.all(
|
|
185
|
+
toolUses.map(async (t): Promise<Anthropic.ToolResultBlockParam> => {
|
|
186
|
+
const handler: ToolHandler | undefined = toolHandlers[t.name];
|
|
187
|
+
if (!handler) {
|
|
188
|
+
return { type: 'tool_result', tool_use_id: t.id, content: `Error: no handler registered for tool "${t.name}"`, is_error: true };
|
|
189
|
+
}
|
|
190
|
+
let input: Record<string, unknown> = {};
|
|
191
|
+
try {
|
|
192
|
+
if (t.partialJson.trim()) input = JSON.parse(t.partialJson);
|
|
193
|
+
} catch (err) {
|
|
194
|
+
return { type: 'tool_result', tool_use_id: t.id, content: `Error parsing tool input: ${(err as Error).message}`, is_error: true };
|
|
195
|
+
}
|
|
196
|
+
try {
|
|
197
|
+
const output = await handler(input);
|
|
198
|
+
return { type: 'tool_result', tool_use_id: t.id, content: output };
|
|
199
|
+
} catch (err) {
|
|
200
|
+
return { type: 'tool_result', tool_use_id: t.id, content: `Error: ${(err as Error).message}`, is_error: true };
|
|
201
|
+
}
|
|
202
|
+
})
|
|
203
|
+
);
|
|
204
|
+
|
|
205
|
+
// Append the assistant's tool_use turn and our tool_result reply.
|
|
206
|
+
const assistantBlocks: Anthropic.ContentBlockParam[] = [];
|
|
207
|
+
if (text.trim()) assistantBlocks.push({ type: 'text', text });
|
|
208
|
+
for (const t of toolUses) {
|
|
209
|
+
let parsedInput: unknown = {};
|
|
210
|
+
try { if (t.partialJson.trim()) parsedInput = JSON.parse(t.partialJson); } catch { /* empty input */ }
|
|
211
|
+
assistantBlocks.push({ type: 'tool_use', id: t.id, name: t.name, input: parsedInput });
|
|
212
|
+
}
|
|
213
|
+
turnMessages.push({ role: 'assistant', content: assistantBlocks });
|
|
214
|
+
turnMessages.push({ role: 'user', content: toolResults });
|
|
106
215
|
}
|
|
107
216
|
|
|
108
|
-
|
|
217
|
+
// Iteration budget exhausted.
|
|
218
|
+
return { completed: false, error: new Error(`Tool-use loop exceeded ${maxIterations} iterations`) };
|
|
109
219
|
} catch (err: unknown) {
|
|
110
220
|
let error: Error;
|
|
111
221
|
if (err instanceof Anthropic.APIError && (err as any).status !== undefined) {
|
|
@@ -27,22 +27,8 @@ export async function chainOfThought(args: ChainOfThoughtArgs): Promise<AgentCom
|
|
|
27
27
|
return { completed: false, error: result.error };
|
|
28
28
|
}
|
|
29
29
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
if (typeof result.value === 'object') {
|
|
33
|
-
parsed = result.value;
|
|
34
|
-
} else {
|
|
35
|
-
let text = result.value as string;
|
|
36
|
-
// Strip markdown code fences if present
|
|
37
|
-
text = text.replace(/^```(?:json)?\s*/i, '').replace(/\s*```\s*$/, '');
|
|
38
|
-
// Extract the first JSON object from the text
|
|
39
|
-
const start = text.indexOf('{');
|
|
40
|
-
const end = text.lastIndexOf('}');
|
|
41
|
-
if (start !== -1 && end > start) {
|
|
42
|
-
text = text.substring(start, end + 1);
|
|
43
|
-
}
|
|
44
|
-
parsed = JSON.parse(text);
|
|
45
|
-
}
|
|
30
|
+
if (typeof result.value === 'object') {
|
|
31
|
+
const parsed = result.value as any;
|
|
46
32
|
return {
|
|
47
33
|
completed: true,
|
|
48
34
|
value: {
|
|
@@ -50,7 +36,36 @@ export async function chainOfThought(args: ChainOfThoughtArgs): Promise<AgentCom
|
|
|
50
36
|
answer: parsed.answer ?? '',
|
|
51
37
|
},
|
|
52
38
|
};
|
|
53
|
-
} catch {
|
|
54
|
-
return { completed: false, error: new Error('Failed to parse chain-of-thought response') };
|
|
55
39
|
}
|
|
40
|
+
|
|
41
|
+
const rawText = result.value as string;
|
|
42
|
+
let text = rawText.replace(/^```(?:json)?\s*/i, '').replace(/\s*```\s*$/, '');
|
|
43
|
+
const start = text.indexOf('{');
|
|
44
|
+
const end = text.lastIndexOf('}');
|
|
45
|
+
if (start !== -1 && end > start) {
|
|
46
|
+
const candidate = text.substring(start, end + 1);
|
|
47
|
+
try {
|
|
48
|
+
const parsed = JSON.parse(candidate);
|
|
49
|
+
return {
|
|
50
|
+
completed: true,
|
|
51
|
+
value: {
|
|
52
|
+
explanation: parsed.explanation ?? '',
|
|
53
|
+
answer: parsed.answer ?? '',
|
|
54
|
+
},
|
|
55
|
+
};
|
|
56
|
+
} catch (err) {
|
|
57
|
+
console.error('chainOfThought: JSON.parse failed:', (err as Error).message);
|
|
58
|
+
console.error('chainOfThought: raw response was:', rawText);
|
|
59
|
+
}
|
|
60
|
+
} else {
|
|
61
|
+
console.error('chainOfThought: no JSON object found in response. Raw text:', rawText);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// Graceful fallback: model returned prose without parseable JSON.
|
|
65
|
+
// Treat the full text as the answer so the user still sees something useful.
|
|
66
|
+
const fallback = rawText.trim();
|
|
67
|
+
if (fallback) {
|
|
68
|
+
return { completed: true, value: { explanation: '', answer: fallback } };
|
|
69
|
+
}
|
|
70
|
+
return { completed: false, error: new Error('Empty response from model') };
|
|
56
71
|
}
|
package/src/models/index.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
export { ProviderName, ProviderConfig, ModelEntry, Provider, SystemMessage, UserMessage, Message, AgentCompletion, completePrompt, PromptCompletionArgs, AgentArgs, RequestError, TextBlock, ImageBlock, ContentBlock, MessageContent, isMultimodalContent } from './types';
|
|
2
|
-
export { AnthropicProvider, OpenAIProvider, PROVIDERS, getProvider, detectProvider } from './providers';
|
|
1
|
+
export { ProviderName, ProviderConfig, ModelEntry, Provider, SystemMessage, UserMessage, Message, AgentCompletion, completePrompt, PromptCompletionArgs, AgentArgs, RequestError, TextBlock, ImageBlock, ContentBlock, MessageContent, isMultimodalContent, ToolDefinition, ToolHandler } from './types';
|
|
2
|
+
export { AnthropicProvider, OpenAIProvider, ClaudeCodeProvider, PROVIDERS, getProvider, detectProvider } from './providers';
|
|
3
3
|
export { anthropic, AnthropicArgs, buildAnthropicRequest } from './anthropic';
|
|
4
4
|
export { openai, OpenaiArgs, buildOpenAIRequest } from './openai';
|
|
5
5
|
export { fireworksai, FireworksAIArgs, resolveFireworksModel, buildFireworksRequest } from './fireworksai';
|
package/src/models/providers.ts
CHANGED
|
@@ -2,8 +2,8 @@ import { Provider, ProviderName } from './types';
|
|
|
2
2
|
|
|
3
3
|
export const AnthropicProvider: Provider = {
|
|
4
4
|
name: 'Anthropic',
|
|
5
|
-
builderModels: ['claude-opus-4-6', 'claude-sonnet-4-
|
|
6
|
-
chatModels: ['claude-sonnet-4-
|
|
5
|
+
builderModels: ['claude-opus-4-6', 'claude-sonnet-4-6'],
|
|
6
|
+
chatModels: ['claude-sonnet-4-6','claude-haiku-4-5'],
|
|
7
7
|
detectModel(model: string): boolean {
|
|
8
8
|
return model.startsWith('claude-');
|
|
9
9
|
}
|
|
@@ -27,7 +27,16 @@ export const FireworksAIProvider: Provider = {
|
|
|
27
27
|
}
|
|
28
28
|
};
|
|
29
29
|
|
|
30
|
-
export const
|
|
30
|
+
export const ClaudeCodeProvider: Provider = {
|
|
31
|
+
name: 'ClaudeCode',
|
|
32
|
+
builderModels: ['claude-opus-4-6', 'claude-sonnet-4-6'],
|
|
33
|
+
chatModels: ['claude-sonnet-4-6', 'claude-haiku-4-5'],
|
|
34
|
+
detectModel(_model: string): boolean {
|
|
35
|
+
return false; // Never auto-detect — must be explicitly selected
|
|
36
|
+
}
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
export const PROVIDERS: Provider[] = [AnthropicProvider, OpenAIProvider, FireworksAIProvider, ClaudeCodeProvider];
|
|
31
40
|
|
|
32
41
|
export function getProvider(name: ProviderName): Provider {
|
|
33
42
|
const provider = PROVIDERS.find(p => p.name === name);
|
package/src/models/types.ts
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
// Provider types
|
|
3
3
|
// ---------------------------------------------------------------------------
|
|
4
4
|
|
|
5
|
-
export type ProviderName = 'Anthropic' | 'OpenAI' | 'FireworksAI';
|
|
5
|
+
export type ProviderName = 'Anthropic' | 'OpenAI' | 'FireworksAI' | 'ClaudeCode';
|
|
6
6
|
|
|
7
7
|
export interface ProviderConfig {
|
|
8
8
|
apiKey: string;
|
|
@@ -69,6 +69,18 @@ export interface UserMessage {
|
|
|
69
69
|
name?: string;
|
|
70
70
|
}
|
|
71
71
|
|
|
72
|
+
// ---------------------------------------------------------------------------
|
|
73
|
+
// Tool use
|
|
74
|
+
// ---------------------------------------------------------------------------
|
|
75
|
+
|
|
76
|
+
export interface ToolDefinition {
|
|
77
|
+
name: string;
|
|
78
|
+
description: string;
|
|
79
|
+
input_schema: Record<string, unknown>;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
export type ToolHandler = (input: Record<string, unknown>) => Promise<string>;
|
|
83
|
+
|
|
72
84
|
// ---------------------------------------------------------------------------
|
|
73
85
|
// Completions
|
|
74
86
|
// ---------------------------------------------------------------------------
|
|
@@ -91,6 +103,14 @@ export interface PromptCompletionArgs {
|
|
|
91
103
|
cacheSystem?: boolean;
|
|
92
104
|
/** JSON schema for structured output via constrained decoding (Anthropic output_config). */
|
|
93
105
|
outputSchema?: Record<string, unknown>;
|
|
106
|
+
/** Tools the model may invoke before producing its final answer. */
|
|
107
|
+
tools?: ToolDefinition[];
|
|
108
|
+
/** Executors for each tool name. Required when `tools` is set. */
|
|
109
|
+
toolHandlers?: Record<string, ToolHandler>;
|
|
110
|
+
/** Max tool-use rounds before the loop aborts. Default: 3. */
|
|
111
|
+
maxToolIterations?: number;
|
|
112
|
+
/** Fired once per tool-use iteration with the names of tools about to execute. */
|
|
113
|
+
onToolCall?: (names: string[]) => void;
|
|
94
114
|
}
|
|
95
115
|
|
|
96
116
|
export type completePrompt<TValue = string> = (args: PromptCompletionArgs) => Promise<AgentCompletion<TValue>>;
|