Commit Graph
100 Commits
Author SHA1 Message Date
Mario Zechner 3db2a6fe2c Expose agent, agentInterface, and artifactsPanel as public in ChatPanel
Make these properties public so they can be accessed externally for
test automation and other programmatic control.

Changes:
- Change agent, agentInterface, artifactsPanel from private to public
2025-10-10 11:40:07 +02:00
Mario Zechner 2756f2a974 Refactor JavaScript REPL tool description with consistent pattern
Clean up and restructure JavaScript REPL description following consistent pattern:
- Purpose section
- When to Use section
- Environment section
- Common Libraries section
- Important Notes section
- Example section

Removed buildJavaScriptReplDescription() function - no longer dynamically
injecting runtime provider docs into tool description (will move to system prompt).

Changes:
- Replace JAVASCRIPT_REPL_BASE_DESCRIPTION with JAVASCRIPT_REPL_DESCRIPTION
- Remove JAVASCRIPT_REPL_CHART_EXAMPLE and JAVASCRIPT_REPL_FOOTER
- Remove buildJavaScriptReplDescription() function
- Update javascript-repl tool to use static description
- Simpler, more scannable structure with clear hierarchy
2025-10-10 11:31:11 +02:00
Mario Zechner 3337953b2a Improve artifacts tool description to emphasize update command
Add clear decision tree and anti-patterns to prevent LLMs from using
get + rewrite when they should use update for targeted edits.

Changes:
- Add CRITICAL workflow section at top with decision tree
- Emphasize 'update' as PREFERRED for edits (token efficient)
- Mark 'rewrite' as LAST RESORT only
- Add ANTI-PATTERNS section showing wrong approaches
- Clarify use cases for each command
- Add examples emphasizing surgical modifications
2025-10-10 02:32:19 +02:00
Mario Zechner ab9137542c Clarify when to use artifacts runtime functions vs artifacts tool
Make it clear that runtime functions are ONLY for programmatically generated
content (by code), not for content the LLM authors directly.

Changes:
- Add WHEN TO USE and DO NOT USE sections to runtime provider description
- Emphasize that createOrUpdateArtifact is for code-generated content
- Point users to artifacts tool for LLM-authored content like summaries
2025-10-10 02:10:36 +02:00
Mario Zechner 2e56f77599 Replace hasArtifact with listArtifacts
LLMs don't need to check existence - they can just list all artifacts.
Simpler API that returns all filenames at once.

Changes:
- Replace hasArtifact(filename) with listArtifacts() returning string[]
- Add 'list' action handler that returns all artifact keys
- Update examples in prompt to use listArtifacts()
2025-10-10 01:49:03 +02:00
Mario Zechner 7a859cbe52 Merge createArtifact and updateArtifact into createOrUpdateArtifact
LLMs get confused about when to use create vs update. The single function
automatically detects if the artifact exists and chooses the right operation.

Changes:
- Replace createArtifact/updateArtifact with createOrUpdateArtifact in runtime
- Update handler to check existence and use appropriate command (create/rewrite)
- Simplify prompt documentation and examples
2025-10-10 01:43:36 +02:00
Mario Zechner 961112ff83 Fix abort detection to use message stopReason instead of global isStreaming
When abort happens during tool call streaming, the tool result should show as aborted.
Previously used global isStreaming state which would flip when new messages streamed in,
causing spinner to reappear incorrectly.

Changes:
- Use message.stopReason === "aborted" to detect aborted tool calls
- Create synthetic error result for aborted tool calls in ToolMessage component
- Fix Ollama provider key test to return true (can't know which model to test)
- Add newline before HTML execution logs in artifacts update
2025-10-10 01:40:59 +02:00
Mario Zechner 6bc098e57b HTML artifacts call window.complete() when page loads
- Inject <script>if (window.complete) window.complete();</script> before </html>
- HTML artifacts are long-running and don't time out
- Console logs are sent immediately, completion signals when page is ready
- Removes need for artificial timeout in HTML artifacts
2025-10-09 23:49:22 +02:00
Mario Zechner 695bcf9b6f Simplify ArtifactsRuntimeProvider constructor
- Take artifactsPanel and agent directly instead of 5 separate function parameters
- Define minimal ArtifactsPanelLike and AgentLike interfaces to avoid circular deps
- Update all call sites (ChatPanel, browser-javascript) to use simplified constructor
- Much cleaner and easier to use
2025-10-09 23:37:14 +02:00
Mario Zechner c0ad46fa01 Fix javascript-repl to throw errors on execution failure
- Throw error instead of returning output when result.success is false
- Ensures tool call is marked as failed when code execution fails or is aborted
- Matches browser-javascript error handling pattern
2025-10-09 23:30:40 +02:00
Mario Zechner 4ac774cbbb Fix console logging and message routing
Console Logging Improvements:
- Changed ConsoleRuntimeProvider to send logs immediately instead of batching
- Track pending send promises and await them in onCompleted callback
- Ensures REPL gets all logs before execution-complete
- Enables real-time console logging for HTML artifacts

Message Routing Fixes:
- Remove "handled" concept from message routing - broadcast all messages to all providers/consumers
- Change handleMessage return type from Promise<boolean> to Promise<void>
- Add debug logging to RuntimeMessageRouter to trace message flow
- Fix duplicate error logging (window error handler now only tracks errors, doesn't log them)

Output Formatting Consistency:
- Remove [LOG], [ERROR] prefixes from console output in both tools
- Show console logs before error messages
- Use "=> value" format for return values in both javascript-repl and browser-javascript
- Remove duplicate "Error:" prefix and extra formatting

Bug Fixes:
- Fix race condition where execution-complete arrived before console logs
- Fix ConsoleRuntimeProvider blocking execution-complete from reaching consumers
- Remove duplicate console log collection from SandboxedIframe
- Fix return value capture by wrapping user code in async function
2025-10-09 23:20:14 +02:00
Mario Zechner 38aaaee968 Remove debug console.log statements causing duplicate error messages
- console.log('Reporting execution error:', finalError) was logging the error
- This caused duplicate error message in output
- Removed all debug console.log statements from window.complete()
- Error is only shown via execution-error message now
2025-10-09 20:53:32 +02:00
Mario Zechner 8747e01c31 Display return values and fix duplicate error messages in REPL
- javascript-repl now displays return values with => prefix
- Objects are JSON.stringify'd with formatting
- Removed console.error from wrapper to prevent duplicate error messages
- Error is already captured and sent via execution-error message
- Fixes missing return value display and duplicate error output
2025-10-09 20:51:25 +02:00
Mario Zechner 5fc3857666 Pass return value through execution-complete message instead of logging
- Return value now passed to window.complete(error, returnValue)
- execution-complete message includes returnValue field
- SandboxResult interface updated to include returnValue
- executionConsumer passes returnValue in resolved promise
- Return values properly captured and available to callers
2025-10-09 20:47:26 +02:00
Mario Zechner 9a3f01fcb8 Fix REPL timeout with return statements by wrapping user code in function
- User code with return statement was exiting the async IIFE early
- Completion callbacks and window.complete() were never reached
- Now wrap user code in userCodeFunc to capture return value
- Return statement returns from userCodeFunc, not outer IIFE
- Completion callbacks and window.complete() always execute
- Return value is logged to console output
- Fixes 30-second timeout when using return statements in REPL
2025-10-09 20:43:39 +02:00
Mario Zechner fdd4e24246 Fix message routing by broadcasting to all providers and consumers
- Router was stopping propagation after first handler returned true
- This prevented consumers from seeing messages that providers handled
- executionConsumer never received execution-complete because ConsoleRuntimeProvider handled it first
- Now all providers and consumers receive all messages
- Fixes javascript_repl never completing
2025-10-09 20:41:22 +02:00
Mario Zechner 3f29ce9cb6 Fix ConsoleRuntimeProvider blocking execution-complete from reaching executionConsumer
- ConsoleRuntimeProvider was handling execution-complete and returning true
- This stopped message propagation before executionConsumer could handle it
- ExecutionConsumer never got execution-complete, so promise never resolved
- Now ConsoleRuntimeProvider responds but returns false to allow propagation
- Fixes javascript_repl never completing (30s timeout)
2025-10-09 20:39:04 +02:00
Mario Zechner 5dcb5ecc89 Fix race condition by making window.complete() async and awaiting it
- window.complete() was fire-and-forget, causing execution-complete to arrive before console messages
- This caused sandbox to unregister before console message responses arrived
- Made complete() async and await sendRuntimeMessage()
- SandboxedIframe wrapper now awaits window.complete()
- Ensures all messages are processed before cleanup/unregister
- Fixes 30-second timeout on javascript_repl
2025-10-09 20:31:48 +02:00
Mario Zechner bb138307b1 Fix ConsoleRuntimeProvider hanging by calling respond()
- ConsoleRuntimeProvider.handleMessage() was not calling respond()
- This caused sendRuntimeMessage() to hang waiting for response (30s timeout)
- Now properly acknowledges console, execution-complete, and execution-error messages
- Fixes javascript_repl hanging on simple console.log() calls
2025-10-09 20:27:02 +02:00
Mario Zechner 33418d9dea Unify completion callback pattern across browser-javascript and javascript-repl
- Remove fallback timeout from ConsoleRuntimeProvider (was causing 2s delays)
- Add completion callback support to SandboxedIframe REPL wrapper
- Call completion callbacks before window.complete() in both success/error paths
- Both browser-javascript and javascript-repl now use identical completion pattern
- Ensures console logs are batched and sent before execution completes
2025-10-09 20:24:20 +02:00
Mario Zechner 6983ad4eaa Simplify ConsoleRuntimeProvider to batch-send logs at completion only 2025-10-09 20:16:32 +02:00
Mario Zechner af0297cd16 Add onCompleted callback system for guaranteed console log delivery
- Add onCompleted() callback registration in RuntimeMessageBridge
- Modify wrapperFunction to call completion callbacks before returning
- Update ConsoleRuntimeProvider to immediate send + completion batch pattern
- Extract DOWNLOADABLE_FILE_RUNTIME_DESCRIPTION from ATTACHMENTS_RUNTIME_DESCRIPTION
- Logs sent immediately (fire-and-forget), unsent logs batched at completion
- Ensures all console logs arrive before tool execution completes
2025-10-09 20:10:20 +02:00
Mario Zechner b288cd9448 Add debug logging to RuntimeMessageRouter and increase API key validation tokens
- Add console.log for user script messages in RuntimeMessageRouter
- Increase ProviderKeyInput maxTokens from 10 to 200 for better validation
2025-10-09 18:57:43 +02:00
Mario Zechner c2793d8017 Add runtime bridge architecture and fix HTML escaping
Major refactoring to unify runtime providers across sandbox and user script contexts:

1. Runtime Bridge & Router
   - Add RuntimeMessageBridge for unified messaging abstraction
   - Rename SandboxMessageRouter → RuntimeMessageRouter
   - Router now handles both iframe and user script messages
   - Guard for non-extension environments

2. Provider Refactoring
   - ArtifactsRuntimeProvider: Add offline mode with snapshot fallback
   - AttachmentsRuntimeProvider: Remove returnDownloadableFile (moved to dedicated provider)
   - ConsoleRuntimeProvider: Add message collection, remove lifecycle logic
   - FileDownloadRuntimeProvider: New provider for file downloads

3. HTML Escaping Fix
   - Escape </script> in JSON.stringify output to prevent premature tag closure
   - Applies when injecting provider data into <script> tags
   - JavaScript engine automatically unescapes, no runtime changes needed

4. Function Renaming
   - listFiles → listAttachments
   - readTextFile → readTextAttachment
   - readBinaryFile → readBinaryAttachment
   - returnFile → returnDownloadableFile

5. Updated Exports
   - Export new RuntimeMessageBridge and RuntimeMessageRouter
   - Export FileDownloadRuntimeProvider
   - Update all cross-references

This sets the foundation for reusing providers in browser-javascript tool.
2025-10-09 17:32:45 +02:00
Mario Zechner d7d79bd533 Add image artifact support with proper binary downloads
- Add ImageArtifact component for displaying images (.png, .jpg, .jpeg, .gif, .webp, .bmp, .ico)
- Images stored as base64, displayed via data URLs
- Download button properly decodes base64 to Uint8Array for valid binary downloads
- Fix Lit ChildPart error: use CSS rotation instead of innerHTML manipulation in collapsible headers

Changes:
- web-ui/src/tools/artifacts/ImageArtifact.ts: New image artifact component
- web-ui/src/tools/artifacts/artifacts.ts: Add "image" file type support
- web-ui/src/tools/renderer-registry.ts: Fix collapsible chevron to use CSS rotation
- web-ui/src/index.ts: Export ImageArtifact
2025-10-09 04:34:42 +02:00
Mario Zechner 9687551324 Don't access innerHTML like that or lit kills itself. 2025-10-09 04:26:03 +02:00
Mario Zechner 4d2ca6ab2a Add artifact message persistence for session reconstruction
- Add ArtifactMessage type as core part of AppMessage union (not CustomMessages)
- ArtifactsRuntimeProvider appends artifact messages on create/update/delete
- MessageList filters out artifact messages (UI display only)
- artifacts.ts reconstructFromMessages handles artifact messages
- Export ARTIFACTS_RUNTIME_PROVIDER_DESCRIPTION from main index
- Fix artifact creation bug: pass filename as title instead of mimeType

Changes:
- web-ui/src/components/Messages.ts: Add ArtifactMessage to BaseMessage union
- web-ui/src/components/MessageList.ts: Skip artifact messages in render
- web-ui/src/components/sandbox/ArtifactsRuntimeProvider.ts: Append messages, fix title parameter
- web-ui/src/ChatPanel.ts: Pass agent.appendMessage callback
- web-ui/src/tools/artifacts/artifacts.ts: Handle artifact messages in reconstructFromMessages
- web-ui/src/index.ts: Export ARTIFACTS_RUNTIME_PROVIDER_DESCRIPTION
- web-ui/example/src/custom-messages.ts: Update message transformer to filter artifacts
2025-10-09 04:07:59 +02:00
Mario Zechner 0eaa879d46 Fix various sandbox issues. 2025-10-08 22:51:32 +02:00
Mario Zechner 91c1dc6475 Add ollama dependency and dialog backdrop blur
- Add ollama package to web-ui dependencies for ModelSelector
- Add backdrop blur to SettingsDialog (bg-black/50 backdrop-blur-sm)
- Update mini-lit to 0.1.9 for backdropClassName prop support
- Fix TypeScript errors in ModelSelector (ollama import, parameter types)
- Add backward compatibility methods to SessionsStore (saveSession, loadSession, getLatestSessionId)
2025-10-08 17:49:56 +02:00
Mario Zechner db34ef01bf Fix IndexedDB in-line vs out-of-line key handling
- Check if store has keyPath before calling put()
- If keyPath exists (in-line keys), only pass value: store.put(value)
- If no keyPath (out-of-line keys), pass both: store.put(value, key)
- Apply fix to both set() and transaction.set()
- Fixes DataError when saving sessions with keyPath: 'id'
2025-10-08 16:53:54 +02:00
Mario Zechner 0de89a750e Refactor to Store-based architecture
- Create base Store class with private backend and protected getBackend()
- Add SettingsStore, ProviderKeysStore, SessionsStore
- Each store defines its own schema via getConfig()
- AppStorage now takes stores + backend in constructor
- Remove SessionsRepository (logic moved to SessionsStore)
- Update all consumers to use store API (storage.settings.get/set, storage.providerKeys.get/set)
- Update example app to follow new pattern: create stores, gather configs, create backend, wire
- Benefits: stores own their schema, no circular deps, cleaner separation
2025-10-08 16:41:02 +02:00
Mario Zechner bbbc232c7c Implement unified storage architecture
- Replace fragmented storage backends with single IndexedDBStorageBackend
- Create multi-store StorageBackend interface (storeName parameter)
- Remove old backends: IndexedDBBackend, LocalStorageBackend, SessionIndexedDBBackend, WebExtensionStorageBackend
- Remove old repositories: ProviderKeysRepository, SessionRepository, SettingsRepository
- Simplify AppStorage to directly expose storage methods (getSetting/setSetting, getProviderKey/setProviderKey)
- Create SessionsRepository for session-specific operations
- Update all consumers to use new simplified API
- Update example app to use new storage architecture
- Benefits: 10GB+ quota (vs 10MB chrome.storage), single database, consistent API
2025-10-08 16:14:29 +02:00
Mario Zechner b3cce7b400 Fix spinner showing on aborted tool calls in javascript-repl and artifacts renderers
When isStreaming is false and there's no result (aborted state), show 'complete' state instead of 'inprogress' to avoid showing the spinner.
2025-10-08 14:43:23 +02:00
Mario Zechner 46b1abff1d Add cursor-pointer to collapsible header button 2025-10-08 14:17:48 +02:00
Mario Zechner 9a57aa7e1a Prevent default and stop propagation when clicking artifact pill
This prevents the collapsible header from toggling when the pill is clicked.
2025-10-08 14:17:04 +02:00
Mario Zechner 8e017db924 Export ArtifactPill from web-ui index 2025-10-08 14:13:23 +02:00
Mario Zechner 3adc8357b1 Make openArtifact public and remove type cast in ArtifactPill 2025-10-08 14:12:52 +02:00
Mario Zechner 58b9c36268 Make renderHeader and renderCollapsibleHeader accept string | TemplateResult
- Update renderHeader and renderCollapsibleHeader in renderer-registry.ts to accept `text: string | TemplateResult`
- Remove duplicated renderCollapsibleHeaderWithPill helper in artifacts-tool-renderer.ts
- Update all artifact renderer calls to use renderHeaderWithPill() inline
- Remove all separate pill rendering below headers

This allows artifact pills to be rendered inline with header text without code duplication.
2025-10-08 14:12:02 +02:00
Mario Zechner 547be7ce37 Add clickable artifact pills to tool renderer
- Create ArtifactPill component (similar to SkillPill)
- Renders filename as clickable pill with FileCode2 icon
- Clicking pill opens artifacts panel and selects that artifact
- Update ArtifactsToolRenderer to accept artifactsPanel reference
- Pass artifactsPanel from ChatPanel to renderer on initialization
- Display artifact pill below header for all commands
- Pill only clickable when artifactsPanel reference is available
2025-10-08 14:01:25 +02:00
Mario Zechner b3efac4591 Update artifacts-tool-renderer to use collapsible headers
- All actions except DELETE now use collapsible headers
- CREATE/UPDATE/REWRITE/GET/LOGS: code/output collapsed by default
- DELETE: keeps simple non-collapsible header
- Fix isStreaming parameter usage for proper spinner state
- Add smooth 300ms animation on expand/collapse
- Full header is clickable to toggle collapse state
2025-10-08 13:46:52 +02:00
Mario Zechner 1405c47b50 Make entire collapsible header clickable
- Changed outer div to button element
- Added w-full and text-left classes
- Now click anywhere on header (icon, text, chevron) to expand/collapse
2025-10-08 13:44:59 +02:00
Mario Zechner f646a29d1a Add collapsible tool renderers with animated expand/collapse
- Add renderCollapsibleHeader() to renderer-registry
  - Places chevron on right, spinner on left
  - Toggles between ChevronRight (collapsed) and ChevronDown (expanded)
  - Uses max-h-0/max-h-[2000px] with transition-all for smooth animation
  - Dynamically adds/removes mt-3 to avoid margin when collapsed

- Update javascript-repl renderer to use collapsible sections
  - Code and console output hidden by default
  - Only file attachments remain visible
  - 300ms smooth animation on expand/collapse

- Export renderCollapsibleHeader from web-ui index
2025-10-08 13:38:45 +02:00
Mario Zechner 8ec9805112 Refactor artifacts renderer and add Console component
- Extract ArtifactsToolRenderer from ArtifactsPanel into standalone renderer
- Fix ChatPanel to register ArtifactsToolRenderer instead of panel
- Implement command-specific rendering logic (create/update/rewrite/get/logs/delete)
- Create reusable Console component with copy button and autoscroll toggle
- Replace custom console implementation with ExpandableSection and Console
- Fix Lit reactivity for HtmlArtifact logs using spread operator
- Add Lucide icons (FileCode2, ChevronsDown, Lock) for UI consistency
- Follow skill.ts patterns with renderHeader and state handling
- Add i18n strings for all artifact actions and console features
2025-10-08 01:54:50 +02:00
Mario Zechner a8159f504f Make message transformer async, expose i18n. 2025-10-07 17:49:23 +02:00
Mario Zechner f7878c3c71 Rename ChromeStorageBackend to WebExtensionStorageBackend for cross-browser support
- Rename chrome-storage-backend.ts to web-extension-storage-backend.ts
- Update to use globalThis.browser || globalThis.chrome for Firefox/Chrome compatibility
- Export both names for backward compatibility
- Fix tsc --preserveWatchOutput in web-ui dev script to prevent console clearing

This fixes the "browser is not defined" error in Chrome extensions.
2025-10-06 23:48:43 +02:00
Mario Zechner bcd109f2e9 Remove debug console.log from ChatPanel 2025-10-06 19:01:11 +02:00
Mario Zechner 33145c5f24 Make mini-lit a peer dependency in pi-web-ui
- Move mini-lit from dependencies to peerDependencies
- Keep in devDependencies for development
- Prevents bundlers from including mini-lit when consuming pi-web-ui
- Consumer (sitegeist) provides mini-lit, esbuild bundles it once
- Fixes duplicate mini-lit bundling issue permanently
2025-10-06 18:59:08 +02:00
Mario Zechner 6126380879 Update package-lock.json after mini-lit version changes 2025-10-06 18:51:34 +02:00
Mario Zechner 7068c01b44 Remove debug console.log from ChatPanel 2025-10-06 18:40:41 +02:00
Mario Zechner 2dbe7771fd Clean up browser-extension references from monorepo
- Update README.md to reference sitegeist repo
- Update CLAUDE.md to replace browser-extension with web-ui
- Update packages/web-ui/README.md examples to point to sitegeist
- Remove browser-extension exclude from tsconfig.json
- Remove browser-extension from .claude/settings.local.json permissions
2025-10-06 18:40:04 +02:00
Mario Zechner aa005d062a Remove browser-extension package (migrated to separate sitegeist repo)
- Remove packages/browser-extension directory
- Update package.json scripts to remove browser-ext from build and dev
- Extension now lives at https://github.com/badlogic/sitegeist
- Uses file: dependencies to pi-ai and pi-web-ui for development
2025-10-06 18:38:25 +02:00
Mario Zechner 7e79c05407 Fix navigation tracking and ChatPanel window width initialization
Navigation tracking fixes:
- Filter out chrome-extension:// URLs to avoid triggering on extension internal pages
- Fixes "Could not establish connection" errors when sidepanel URL updates
- Remove unused currentTabUrl/currentTabIndex tracking variables

ChatPanel layout fixes:
- Fix windowWidth initialization (was 0 due to too-early evaluation)
- Set windowWidth in connectedCallback after DOM connection
- Add requestAnimationFrame to ensure width is measured after layout
- Add debug logging for troubleshooting layout issues
- Now properly respects BREAKPOINT (800px) for mobile vs desktop layout
2025-10-06 18:26:01 +02:00
Mario Zechner 4f11cc15db Simplify navigation tracking - insert message on every active tab URL change
- Remove complex agent busy state tracking
- Remove checkAndInsertNavMessage helper and onBeforeSend logic
- Directly insert navigation messages when tab URL changes (chrome.tabs.onUpdated)
- Also insert when user switches to a different tab (chrome.tabs.onActivated)
- Much simpler: every URL change = navigation message, no conditions
- Fixes issue where browser_javascript navigation wasn't detected
2025-10-06 17:22:40 +02:00
Mario Zechner 6295025787 Insert navigation messages when agent finishes working (after tool execution)
- Track agent busy state: isStreaming OR pendingToolCalls.size > 0
- When agent transitions from busy to idle, check for URL changes
- Extract checkAndInsertNavMessage() helper function
- Call helper from both onBeforeSend (user submit) and agent state subscription (post-tool)
- Fixes issue where browser_javascript tool navigates page but no nav message inserted
- Navigation messages now appear after tools that change window.location.href
2025-10-06 16:56:51 +02:00
Mario Zechner d0cbca52b3 Tone down navigation badge styling - use card background with shadow instead of primary color 2025-10-06 16:47:11 +02:00
Mario Zechner 4a2ef56954 Only insert navigation messages on user message submit, not during idle browsing
- Remove automatic navigation message insertion from tab change listeners
- Tab listeners now only track current tab state (currentTabUrl, currentTabIndex)
- Navigation messages are only inserted via onBeforeSend callback when user submits
- Prevents spam of navigation messages when user is just browsing without interacting with agent
2025-10-06 16:45:48 +02:00
Mario Zechner c66695f062 Use primary color for navigation badges to improve visibility in light theme 2025-10-06 16:42:47 +02:00
Mario Zechner c825ccf0fa Improve navigation message visibility and favicon handling
- Add fallback favicon using Google's favicon service (s2/favicons API)
- If both tab.favIconUrl and Google service fail, gracefully hide broken image
- Enhance navigation message styling for better visibility:
  - Use accent colors (bg-accent/50 with border-accent) instead of muted secondary
  - Increase padding (px-3 py-2) and add vertical margin (my-2)
  - Add shadow-sm for subtle depth
  - Make title font-medium for better contrast
  - Use border-2 instead of border for more prominence
2025-10-06 16:41:47 +02:00
Mario Zechner 5f04960f6d Fix SessionListDialog behavior and document PersistentStorageDialog bug
- Fix SessionListDialog to not reload when user selects a session after deleting others
  - Track if dialog closed via selection vs other means
  - Only call delete callback if not closed via selection
  - Batch deletions to avoid reload on every delete
- Comment out PersistentStorageDialog in both web-ui example and browser extension (TODO: fix)
- Add Known Bugs section to both README.md files documenting PersistentStorageDialog issue
- Clean up navigation tracking variable names in browser extension
2025-10-06 16:33:33 +02:00
Mario Zechner 2d68594711 Fix new session button and improve navigation message styling
- Add ?new=true query param to prevent auto-loading latest session
- Style navigation message as clickable badge with background
- Add cursor-pointer, truncate, and max-width for proper text overflow
- Click navigation message to open page in new tab
- Show URL on hover
2025-10-06 16:22:27 +02:00
Mario Zechner c9be21ebad Add navigation message tracking to browser extension
- Add onBeforeSend callback to ChatPanel and AgentInterface
- Add onBeforeToolCall callback (for future permission dialogs)
- Create NavigationMessage custom message type
- Add browserMessageTransformer that converts nav messages to <system> tags
- Track last submitted URL and tab index
- Auto-insert navigation message when URL/tab changes on user submit
- Navigation message shows favicon + page title in UI
- LLM receives: <system>Navigated to [title] (tab X): [url]</system>
2025-10-06 13:49:28 +02:00
Mario Zechner 05dfaa11a8 Add custom message extension system with typed renderers and message transformer
- Implement CustomMessages interface for type-safe message extension via declaration merging
- Add MessageRenderer<T> with generic typing for custom message rendering
- Add messageTransformer to Agent for filtering/transforming messages before LLM
- Move message filtering from transports to Agent (separation of concerns)
- Add message renderer registry with typed role support
- Update web-ui example with SystemNotificationMessage demo
- Add custom transformer that converts notifications to <system> tags
- Add SessionListDialog onDelete callback for active session cleanup
- Handle non-existent session IDs in URL (redirect to new session)
- Update both web-ui example and browser extension with session fixes
2025-10-06 13:45:08 +02:00
Mario Zechner cf6b3466f8 Remove refresh. 2025-10-06 12:55:41 +02:00
Mario Zechner e5cf25a267 Refactor agent architecture and add session storage
Major architectural improvements:
- Renamed AgentSession → Agent (state/ → agent/)
- Removed id field from AgentState
- Fixed transport abstraction to pass messages directly instead of using callbacks
- Eliminated circular dependencies in transport creation

Transport changes:
- Changed signature: run(messages, userMessage, config, signal)
- Removed getMessages callback from ProviderTransport and AppTransport
- Transports now filter attachments internally

Session storage:
- Added SessionRepository with IndexedDB backend
- Auto-save sessions after first exchange
- Auto-generate titles from first user message
- Session list dialog with search and delete
- Persistent storage permission dialog
- Browser extension now auto-loads last session

UI improvements:
- ChatPanel creates single AgentInterface instance in setAgent()
- Added drag & drop file upload to MessageEditor
- Fixed artifacts panel auto-opening on session load
- Added "Drop files here" i18n strings
- Changed "Continue Without Saving" → "Continue Anyway"

Web example:
- Complete rewrite of main.ts with clean architecture
- Added check script to package.json
- Session management with URL state
- Editable session titles

Browser extension:
- Added full session storage support
- History and new session buttons
- Auto-load most recent session on open
- Session titles in header
2025-10-06 12:47:52 +02:00
Mario Zechner c18923a8c5 Clean-up 2025-10-06 01:41:00 +02:00
Mario Zechner 9a4e4b086e Remove old plan.md 2025-10-06 01:33:57 +02:00
Mario Zechner 12910a5940 Remove todos folder. 2025-10-05 23:39:37 +02:00
Mario Zechner 53e339ddb8 Enable thinking selector in MessageEditor
- Import Select component from mini-lit and Brain icon from lucide
- Add thinkingLevel property to track current thinking level (off/minimal/low/medium/high)
- Enable showThinkingSelector (was disabled before)
- Add onThinkingChange callback for thinking level changes
- Render Select component with thinking level options when model supports reasoning
- Position thinking selector on left side next to attachment button
- Add i18n translations for Off/Minimal/Low/Medium/High in English and German
- Rename showThinking → showThinkingSelector in AgentInterface and ChatPanel for consistency
- Remove showDebugToggle property from AgentInterface (unused)
- Clean up browser-javascript tool output message (remove CSP note)
2025-10-05 23:32:30 +02:00
Mario Zechner 414a4eb8fd Bump version to 0.5.44 2025-10-05 23:00:59 +02:00
Mario Zechner 0496651308 Add Anthropic prompt caching, pluggable storage, and CORS proxy support
Storage Architecture:
- New pluggable storage system with backends (LocalStorage, ChromeStorage, IndexedDB)
- SettingsRepository for app settings (proxy config, etc.)
- ProviderKeysRepository for API key management
- AppStorage with global accessors (getAppStorage, setAppStorage, initAppStorage)

Transport Refactoring:
- Renamed DirectTransport → ProviderTransport (calls LLM providers with optional CORS proxy)
- Renamed ProxyTransport → AppTransport (uses app server with user auth)
- Updated TransportMode: "direct" → "provider", "proxy" → "app"

CORS Proxy Integration:
- ProviderTransport checks proxy.enabled/proxy.url from storage
- When enabled, modifies model baseUrl to route through proxy: {proxyUrl}/?url={originalBaseUrl}
- ProviderKeyInput test function also honors proxy settings
- Settings dialog with Proxy tab (Switch toggle, URL input, explanatory description)

Anthropic Prompt Caching:
- System prompt cached with cache_control markers (both OAuth and regular API keys)
- Last user message cached to cache conversation history
- Saves 90% on input tokens for cached content (10x cost reduction)

Settings Dialog Improvements:
- Configurable tab system with SettingsTab base class
- ApiKeysTab and ProxyTab as custom elements
- Switch toggle for proxy enable (instead of Checkbox)
- Explanatory paragraphs for each tab
- ApiKeyPromptDialog reuses ProviderKeyInput component

Removed:
- Deprecated ApiKeysDialog (replaced by ProviderKeyInput in SettingsDialog)
- Old storage-adapter and key-store (replaced by new storage architecture)
2025-10-05 23:00:36 +02:00
Mario Zechner 66f092c0c6 Proxy package 2025-10-05 19:02:15 +02:00
Mario Zechner aaea0f4600 Integrate JailJS for CSP-restricted execution in browser extension
Major changes:
- Migrate browser-extension to use web-ui package (85% code reduction)
- Add JailJS content script with ES6+ transform support
- Expose DOM constructors (Event, KeyboardEvent, etc.) to JailJS
- Support top-level await by wrapping code in async IIFE
- Add returnFile() support in JailJS execution
- Refactor KeyStore into pluggable storage-adapter pattern
- Make ChatPanel configurable with sandboxUrlProvider and additionalTools
- Update jailjs to 0.1.1

Files deleted (33 duplicate files):
- All browser-extension components, dialogs, state, tools, utils
- Now using web-ui versions via @mariozechner/pi-web-ui

Files added:
- packages/browser-extension/src/content.ts (JailJS content script)
- packages/web-ui/src/state/storage-adapter.ts
- packages/web-ui/src/state/key-store.ts

Browser extension now has only 5 source files (down from 38).
2025-10-05 16:58:31 +02:00
Mario Zechner f2eecb78d2 web-ui package 2025-10-05 13:30:08 +02:00
Mario Zechner 7159c9734e Update web-ui example to use javascript-repl instead of calculate/getCurrentTime tools 2025-10-04 21:52:30 +02:00
Mario Zechner 9d6267a915 Fix javascript-repl renderer to use console-block component 2025-10-04 21:44:23 +02:00
Mario Zechner 8212623af0 Add JavaScript REPL tool to web-ui package
- Created javascript-repl.ts tool with SandboxedIframe for code execution
- Integrated into ChatPanel replacing calculate and getCurrentTime tools
- REPL provides full browser API access with external library support
- Auto-registers renderer for tool output display
- Uses srcdoc instead of sandbox.html (no CSP restrictions in web apps)
2025-10-04 19:12:38 +02:00
Mario Zechner 0af33ce79a Fix race condition in web-ui SandboxedIframe
Fixed loadContent() and execute() to set srcdoc at the correct time:
- loadContent(): Now sets srcdoc after creating iframe (was missing entirely)
- execute(): Now sets srcdoc after setting up message listeners and creating iframe (was setting before iframe existed)

This prevents missing postMessage events from the sandboxed iframe.
2025-10-04 19:09:17 +02:00
Mario Zechner 5520963841 Better detection of eval/<script> capability on current site wrt CSP 2025-10-04 01:13:07 +02:00
Mario Zechner 3481aeec26 Make browser_javascript tool abortable 2025-10-04 00:45:16 +02:00
Mario Zechner c2427d375c Fix browser javascript tool wrt navigation. Needs to be its own tool call as execution context gets smoked. 2025-10-03 23:48:15 +02:00
Mario Zechner 99983af597 Fix lints. 2025-10-03 23:21:59 +02:00
Mario Zechner 6d046236bf Fix HtmlArtifacts no loading/updating 2025-10-03 11:35:12 +02:00
Mario Zechner 79dd23b6da Restructuring and refactoring 2025-10-03 02:15:37 +02:00
Mario Zechner 3331701e7e Clean-up 2025-10-02 02:48:25 +02:00
Mario Zechner 6a355d7a7e Fix KeyStore for Firefox. 2025-10-02 02:45:38 +02:00
Mario Zechner af426d2682 Fix sandboxed iframe. 2025-10-02 02:41:15 +02:00
Mario Zechner faefc63309 iframe and Firefox fixes 2025-10-02 02:15:33 +02:00
Mario Zechner 4b0703cd5b Artifacts tool, V1, htmlartifact broken due to CSP 2025-10-01 23:32:14 +02:00
Mario Zechner 51f5448a5c Remove tool calls for which there are no results in subsequent user messages. 2025-10-01 22:18:30 +02:00
Mario Zechner 0e932a97df More browser extension work, disable ajv validation in browser extensions, it uses eval/new Function, which is not allowed in manifest v3 extensions 2025-10-01 20:30:49 +02:00
Mario Zechner fc1ef04b6d UX fixes 2025-10-01 18:35:02 +02:00
Mario Zechner d0b2d47b4a More browser extension work. Old interface fully ported. Direct transport. Small UX fixes. 2025-10-01 18:27:40 +02:00
Mario Zechner b3a7b35ec5 Port PDF/Office support, message editor, overlays, key setter 2025-10-01 17:31:13 +02:00
Mario Zechner b67c10dfb1 feat: add cross-browser extension with AI reading assistant
- Create Pi Reader browser extension for Chrome/Firefox
- Chrome uses Side Panel API, Firefox uses Sidebar Action API
- Supports both browsers with separate manifests and unified codebase
- Built with mini-lit components and Tailwind CSS v4
- Features model selection dialog with Ollama support
- Hot reload development server watches both browser builds
- Add useDefineForClassFields: false to fix LitElement reactivity
2025-10-01 04:33:56 +02:00
Mario Zechner c1185c7b95 chore: bump version to 0.5.43 2025-09-19 01:49:46 +02:00
Mario Zechner f55985f633 Fix GPT-5 no-reasoning mode. Somewhat. There's no real off-switch ... 2025-09-19 01:45:00 +02:00
Mario Zechner 0f7ed33ba5 chore: bump version to 0.5.42 2025-09-19 00:14:23 +02:00
Mario Zechner 9e86079386 Fix block indexing in Google provider impl 2025-09-19 00:10:43 +02:00
Mario Zechner 2296dc4052 refactor(ai): improve error handling and stop reason types
- Add 'aborted' as a distinct stop reason separate from 'error'
- Change AssistantMessage.error to errorMessage for clarity
- Update error event to include reason field ('error' | 'aborted')
- Map provider-specific safety/refusal reasons to 'error' stop reason
- Reorganize utility functions into utils/ directory
- Rename agent.ts to agent-loop.ts for better clarity
- Fix error handling in all providers to properly distinguish abort from error
2025-09-18 19:57:13 +02:00
Mario Zechner 293a6e878d chore: bump version to 0.5.41 2025-09-18 11:18:02 +02:00