Skip to content

feat(platform): wire prompt library dialogs into UI#1386

Merged
larryro merged 3 commits into
mainfrom
feat/issue-1331-wire-prompt-library
Apr 11, 2026
Merged

feat(platform): wire prompt library dialogs into UI#1386
larryro merged 3 commits into
mainfrom
feat/issue-1331-wire-prompt-library

Conversation

@yannickmonney
Copy link
Copy Markdown
Contributor

@yannickmonney yannickmonney commented Apr 11, 2026

Summary

  • Wire existing PromptLibraryDialog, SaveAsPromptDialog, and PromptFormDialog components into the UI -- they were fully implemented but unreachable dead code
  • Add a BookOpen button to the chat input toolbar to browse and insert prompt templates
  • Add a Save as prompt button (visible when chat input has content) to save text as a personal prompt template
  • Add a Browse prompts button to the agent instructions page that appends a selected prompt to system instructions
  • Restructure the prompts i18n namespace in en.json to match component key references (nested tabs.*, library.*, actions.*, form.*, scope.*, deleteConfirm.*, saveAs.*)
  • Add complete German translations for the prompts namespace to de.json, de-AT.json, and de-CH.json
  • Fix @ts-expect-error in prompt-library-dialog.tsx by removing the unnecessary type annotation and passing setActiveTab directly to onValueChange
  • Export PromptLibraryDialogProps and SaveAsPromptDialogProps interfaces for lazy component type inference
  • Add accessibility and render tests for all three prompt dialog components

Closes #1331

Test plan

  • Open a chat and verify the BookOpen (prompt library) button appears in the toolbar between Attach and Arena Toggle
  • Click the prompt library button and verify the dialog opens with tabs (All, Team, Personal), search, and prompt cards
  • Select a prompt and verify its content is inserted into the chat input textarea
  • Type text in the chat input and verify the Save (save as prompt) button appears
  • Click save as prompt and verify the dialog opens with the current input pre-filled
  • Navigate to agent instructions and verify the "Browse prompts" button appears next to the system instructions label
  • Select a prompt from agent instructions and verify it appends to the existing system instructions
  • Verify all translation keys resolve correctly (no raw key strings displayed) in English and German
  • Run bun run --filter @tale/platform lint -- passes
  • Run bun run --filter @tale/platform typecheck -- passes
  • Run bunx vitest --run --project client -- all tests pass including new prompt dialog tests
  • Run bunx vitest --run --project server -- all tests pass

Summary by CodeRabbit

  • New Features

    • Added prompt library dialog allowing users to browse and select prompts in chat input.
    • Added ability to save current chat input as a new prompt.
    • Integrated prompt browsing in agent system instructions configuration.
  • Documentation

    • Extended localization support with German (Austria, Switzerland) translations.
    • Updated English translation strings for prompt-related UI.
  • Tests

    • Added test coverage for prompt library, prompt form, and save-as-prompt dialogs.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Apr 11, 2026

📝 Walkthrough

Walkthrough

This pull request implements the Prompt Library feature across the platform by introducing lazy-loaded prompt library and save-as-prompt dialogs in the chat input component and agent instructions page. The changes export prompt dialog type definitions for broader reuse, add comprehensive test coverage for the new dialog components, and expand internationalization support across multiple languages (German variants and English) with new UI strings for prompt management, including library tabs, form labels, actions, and deletion confirmations.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title 'feat(platform): wire prompt library dialogs into UI' accurately describes the main change: integrating existing but unreachable prompt library dialogs into the user-facing UI.
Linked Issues check ✅ Passed The PR fully addresses issue #1331 by wiring prompt library functionality into the UI (chat input toolbar, agent instructions page) and adding translations, enabling users to save, browse, and reuse prompt templates as required.
Out of Scope Changes check ✅ Passed All changes align with the stated objectives: dialog integration, UI controls, translations, type exports, and accessibility tests. No unrelated modifications detected.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/issue-1331-wire-prompt-library

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@greptile-apps greptile-apps Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Your free trial has ended. If you'd like to continue receiving code reviews, you can add a payment method here.

@yannickmonney
Copy link
Copy Markdown
Contributor Author

@coderabbitai review

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Apr 11, 2026

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@larryro larryro force-pushed the feat/issue-1331-wire-prompt-library branch from b881873 to 9ef3513 Compare April 11, 2026 08:03
- Add BookOpen button to chat input toolbar to open PromptLibraryDialog
- Add Save-as-prompt button (visible when input has content) to open
  SaveAsPromptDialog
- Add Browse prompts button to agent instructions page that appends
  selected prompt content to system instructions
- Restructure prompts i18n namespace to match component key references
- Add German translations for prompts namespace (de, de-AT, de-CH)
- Export dialog props interfaces for lazy component type inference
- Remove unused @ts-expect-error and TabValue type from
  prompt-library-dialog
- Add a11y and render tests for all three prompt dialogs

Closes #1331
@larryro larryro force-pushed the feat/issue-1331-wire-prompt-library branch from 9ef3513 to 608330b Compare April 11, 2026 08:05
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 7

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
services/platform/messages/de.json (1)

2803-2817: ⚠️ Potential issue | 🔴 Critical

Resolve the leftover merge conflict before shipping.

<<<<<<< HEAD makes this file invalid JSON, so the German locale will fail to parse/load. It also leaves the final nesting of canvas, promptLibrary, and saveAsPrompt ambiguous.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@services/platform/messages/de.json` around lines 2803 - 2817, The file
contains an unresolved Git merge marker ("<<<<<<< HEAD") that breaks JSON
parsing and makes the final nesting of the "canvas" object and the keys
"promptLibrary" and "saveAsPrompt" ambiguous; remove all conflict markers
("<<<<<<< HEAD", "=======", ">>>>>>> ..."), choose the correct version of the
"canvas" block (or merge fields manually) and ensure the JSON object correctly
includes "canvas", "promptLibrary", and "saveAsPrompt" with proper braces and
commas so the locale parses as valid JSON.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@services/platform/app/features/chat/components/chat-input.tsx`:
- Around line 496-500: The PromptLibraryDialog currently replaces the entire
composer by calling onSelectPrompt={(content) => onChange?.(content)}; instead,
preserve the user's draft by inserting/appending the selected prompt into the
existing composer state—use the current composer value and concatenate or splice
at the cursor and then call onChange with the new combined string (e.g.,
onSelectPrompt={(content) => onChange?.((currentComposerValue ?? '') + content)}
or perform an insertion at the caret if you have cursor position info). Update
PromptLibraryDialog's onSelectPrompt wiring to reference the existing composer
value/state rather than overwriting it.

In
`@services/platform/app/features/prompts/components/__tests__/prompt-form-dialog.test.tsx`:
- Around line 49-62: Replace the unsafe "as never" assertion in the test fixture
for initialData with a properly typed fixture or a satisfies-based pattern so
TypeScript validates the shape; specifically update the initialData object in
prompt-form-dialog.test.tsx (and the similar fixture around lines 88-98) to
either use a helper like createPromptFixture(...) that returns the correct
Prompt type or append "satisfies Prompt" to the literal so the compiler enforces
property shapes (target the initialData symbol and the test file's fixture
declarations when making the change).

In
`@services/platform/app/features/prompts/components/__tests__/prompt-library-dialog.test.tsx`:
- Around line 79-88: Add a test that exercises the full "use prompt" flow:
render PromptLibraryDialog with open={true}, pass spies for onSelectPrompt and
onOpenChange, simulate the user clicking the prompt's "Use" (or equivalent)
button via userEvent.click on the card, then assert that onSelectPrompt was
called with the expected prompt object/ID and that onOpenChange was called to
close the dialog (e.g., calledWith(false) or dialog not in document). Also
assert any usage-increment side-effect observable in the component (e.g., a call
to the increment handler or an updated usage count) by spying/mocking the
relevant handler or verifying updated UI, using the component name
PromptLibraryDialog and prop names onSelectPrompt and onOpenChange to locate
targets.

In
`@services/platform/app/features/prompts/components/__tests__/save-as-prompt-dialog.test.tsx`:
- Around line 46-55: The test claims to verify initialContent but only checks
the title; update the test for SaveAsPromptDialog to assert the textarea is
prefilled by querying the input (e.g., screen.getByDisplayValue("Hello, this is
a test prompt.") or screen.getByRole('textbox') and expect its value to equal
the initialContent), and also supply and mock the component's submit handler
prop (onSubmit/onSave — use the actual prop name the component exposes) then
trigger the submit (click the confirm button) and assert the handler was called
with the expected payload containing the initialContent.

In `@services/platform/messages/de-AT.json`:
- Around line 1-65: de-AT.json is a full duplicate of the base German locale
(all keys under "prompts" and "settings" match de.json); remove or minimize it
so the app falls back to de.json: either delete
services/platform/messages/de-AT.json entirely or replace its contents with an
empty object or only the specific override keys that differ (e.g., any unique
entries under "prompts" or "settings" if needed) so that only Austrian-specific
overrides remain and all identical keys are omitted.

In `@services/platform/messages/de-CH.json`:
- Around line 42-45: The current translation places "form": {"browsePrompts":
"..."} under settings.agents, but the UI expects
settings.agents.knowledge.form.browsePrompts; update the JSON structure so the
"browsePrompts" key is nested under the "knowledge" object (i.e., move or create
"knowledge" and put "form": {"browsePrompts": "Prompts durchsuchen"} inside it)
so the translation is available at settings.agents.knowledge.form.browsePrompts.

In `@services/platform/messages/en.json`:
- Line 1454: The "providers.description" message value is too generic for the
providers table empty state; update the en.json value so it clearly explains the
empty state and next steps (e.g., mention there are no providers yet and how to
add them) so users know what the section is for; locate the key
"providers.description" referenced from providers-table.tsx (line ~143) and
replace "Description" with a concise, actionable sentence like "No providers yet
— add a provider to integrate external services" (or similar copy that fits
tone).

---

Outside diff comments:
In `@services/platform/messages/de.json`:
- Around line 2803-2817: The file contains an unresolved Git merge marker
("<<<<<<< HEAD") that breaks JSON parsing and makes the final nesting of the
"canvas" object and the keys "promptLibrary" and "saveAsPrompt" ambiguous;
remove all conflict markers ("<<<<<<< HEAD", "=======", ">>>>>>> ..."), choose
the correct version of the "canvas" block (or merge fields manually) and ensure
the JSON object correctly includes "canvas", "promptLibrary", and "saveAsPrompt"
with proper braces and commas so the locale parses as valid JSON.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: ce89b83f-a060-4257-b95f-e2470bebfdbc

📥 Commits

Reviewing files that changed from the base of the PR and between d59c2b9 and 9ef3513.

📒 Files selected for processing (11)
  • services/platform/app/features/chat/components/chat-input.tsx
  • services/platform/app/features/prompts/components/__tests__/prompt-form-dialog.test.tsx
  • services/platform/app/features/prompts/components/__tests__/prompt-library-dialog.test.tsx
  • services/platform/app/features/prompts/components/__tests__/save-as-prompt-dialog.test.tsx
  • services/platform/app/features/prompts/components/prompt-library-dialog.tsx
  • services/platform/app/features/prompts/components/save-as-prompt-dialog.tsx
  • services/platform/app/routes/dashboard/$id/agents/$agentId/instructions.tsx
  • services/platform/messages/de-AT.json
  • services/platform/messages/de-CH.json
  • services/platform/messages/de.json
  • services/platform/messages/en.json

Comment on lines +496 to +500
<PromptLibraryDialog
open={promptLibraryOpen}
onOpenChange={setPromptLibraryOpen}
onSelectPrompt={(content) => onChange?.(content)}
/>
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Don't overwrite the user's draft when inserting a prompt.

This replaces the entire composer value with the selected prompt, so any in-progress message is lost. The feature is described as inserting prompts; this wiring should append or insert into the current text instead of clobbering it.

💡 Minimal fix
       <PromptLibraryDialog
         open={promptLibraryOpen}
         onOpenChange={setPromptLibraryOpen}
-        onSelectPrompt={(content) => onChange?.(content)}
+        onSelectPrompt={(content) => {
+          const separator = value.trim() ? '\n\n' : '';
+          onChange?.(value + separator + content);
+        }}
       />
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
<PromptLibraryDialog
open={promptLibraryOpen}
onOpenChange={setPromptLibraryOpen}
onSelectPrompt={(content) => onChange?.(content)}
/>
<PromptLibraryDialog
open={promptLibraryOpen}
onOpenChange={setPromptLibraryOpen}
onSelectPrompt={(content) => {
const separator = value.trim() ? '\n\n' : '';
onChange?.(value + separator + content);
}}
/>
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@services/platform/app/features/chat/components/chat-input.tsx` around lines
496 - 500, The PromptLibraryDialog currently replaces the entire composer by
calling onSelectPrompt={(content) => onChange?.(content)}; instead, preserve the
user's draft by inserting/appending the selected prompt into the existing
composer state—use the current composer value and concatenate or splice at the
cursor and then call onChange with the new combined string (e.g.,
onSelectPrompt={(content) => onChange?.((currentComposerValue ?? '') + content)}
or perform an insertion at the caret if you have cursor position info). Update
PromptLibraryDialog's onSelectPrompt wiring to reference the existing composer
value/state rather than overwriting it.

Comment on lines +49 to +62
initialData={{
_id: 'prompt-1' as never,
_creationTime: 1700000000000,
organizationId: 'test-org-id',
createdBy: 'user-1',
title: 'Existing Prompt',
content: 'Some content',
description: 'A description',
scope: 'personal',
category: 'general',
tags: ['tag1'],
usageCount: 3,
isPublished: true,
}}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick | 🔵 Trivial

Avoid as never in these test fixtures.

This bypasses the type checker exactly where the fixture should catch shape drift in initialData. Please switch to a typed fixture helper or a satisfies-based pattern instead of nullifying the type system.

Based on learnings, "prefer the 'satisfies' operator over 'as' type assertions for config objects and test data."

Also applies to: 88-98

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@services/platform/app/features/prompts/components/__tests__/prompt-form-dialog.test.tsx`
around lines 49 - 62, Replace the unsafe "as never" assertion in the test
fixture for initialData with a properly typed fixture or a satisfies-based
pattern so TypeScript validates the shape; specifically update the initialData
object in prompt-form-dialog.test.tsx (and the similar fixture around lines
88-98) to either use a helper like createPromptFixture(...) that returns the
correct Prompt type or append "satisfies Prompt" to the literal so the compiler
enforces property shapes (target the initialData symbol and the test file's
fixture declarations when making the change).

Comment on lines +79 to +88
it('renders prompt cards when open', () => {
render(
<PromptLibraryDialog
open={true}
onOpenChange={vi.fn()}
onSelectPrompt={vi.fn()}
/>,
);
expect(screen.getByText('Test Prompt')).toBeInTheDocument();
});
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion | 🟠 Major

The main “use prompt” flow is still untested.

This only proves the card renders. It would not catch a broken onSelectPrompt, missed usage increment, or dialog-close-on-use regression, which are the load-bearing behaviors for this feature.

As per coding guidelines, "Tests should cover happy paths, edge cases, and error conditions."

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@services/platform/app/features/prompts/components/__tests__/prompt-library-dialog.test.tsx`
around lines 79 - 88, Add a test that exercises the full "use prompt" flow:
render PromptLibraryDialog with open={true}, pass spies for onSelectPrompt and
onOpenChange, simulate the user clicking the prompt's "Use" (or equivalent)
button via userEvent.click on the card, then assert that onSelectPrompt was
called with the expected prompt object/ID and that onOpenChange was called to
close the dialog (e.g., calledWith(false) or dialog not in document). Also
assert any usage-increment side-effect observable in the component (e.g., a call
to the increment handler or an updated usage count) by spying/mocking the
relevant handler or verifying updated UI, using the component name
PromptLibraryDialog and prop names onSelectPrompt and onOpenChange to locate
targets.

Comment on lines +46 to +55
it('renders with initial content when open', () => {
render(
<SaveAsPromptDialog
open={true}
onOpenChange={vi.fn()}
initialContent="Hello, this is a test prompt."
/>,
);
expect(screen.getByText('prompts.saveAs.title')).toBeInTheDocument();
});
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion | 🟠 Major

This test never verifies the initialContent behavior it names.

It only checks the dialog title, so a regression where the textarea is no longer prefilled would still pass. Please assert the field value, and ideally the submit payload as well.

As per coding guidelines, "Tests should cover happy paths, edge cases, and error conditions."

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@services/platform/app/features/prompts/components/__tests__/save-as-prompt-dialog.test.tsx`
around lines 46 - 55, The test claims to verify initialContent but only checks
the title; update the test for SaveAsPromptDialog to assert the textarea is
prefilled by querying the input (e.g., screen.getByDisplayValue("Hello, this is
a test prompt.") or screen.getByRole('textbox') and expect its value to equal
the initialContent), and also supply and mock the component's submit handler
prop (onSubmit/onSave — use the actual prop name the component exposes) then
trigger the submit (click the confirm button) and assert the handler was called
with the expected payload containing the initialContent.

Comment on lines +1 to +65
{
"prompts": {
"tabs": {
"all": "Alle",
"team": "Team",
"personal": "Persönlich"
},
"library": {
"title": "Prompt-Bibliothek",
"description": "Prompt-Vorlagen durchsuchen, speichern und teilen.",
"searchPlaceholder": "Prompts suchen...",
"loading": "Prompts werden geladen...",
"empty": "Noch keine Prompts. Erstelle deine erste Prompt-Vorlage."
},
"actions": {
"create": "Prompt erstellen",
"createFirst": "Ersten Prompt erstellen",
"edit": "Bearbeiten",
"delete": "Löschen",
"use": "Verwenden",
"usePrompt": "Diesen Prompt verwenden",
"more": "Weitere Aktionen"
},
"deleteConfirm": {
"title": "Prompt löschen",
"description": "Bist du sicher, dass du \"{title}\" löschen möchtest? Diese Aktion kann nicht rückgängig gemacht werden."
},
"scope": {
"global": "Global (alle)",
"team": "Team",
"personal": "Persönlich"
},
"form": {
"createTitle": "Prompt erstellen",
"createDescription": "Eine neue Prompt-Vorlage erstellen.",
"editTitle": "Prompt bearbeiten",
"editDescription": "Die Prompt-Vorlage aktualisieren.",
"titleLabel": "Titel",
"titlePlaceholder": "Prompt-Titel eingeben...",
"contentLabel": "Inhalt",
"contentPlaceholder": "Prompt-Inhalt eingeben...",
"descriptionLabel": "Beschreibung",
"descriptionPlaceholder": "Kurze Beschreibung des Prompts...",
"scopeLabel": "Sichtbarkeit",
"categoryLabel": "Kategorie",
"categoryPlaceholder": "z.B. Schreiben, Analyse, Programmierung",
"tagsLabel": "Tags",
"tagsPlaceholder": "Kommagetrennte Tags...",
"save": "Speichern",
"create": "Erstellen"
},
"saveAs": {
"title": "Als Prompt speichern",
"description": "Den aktuellen Text als wiederverwendbare Prompt-Vorlage speichern."
},
"usageCount": "{count, plural, one {# Verwendung} other {# Verwendungen}}"
},
"settings": {
"agents": {
"form": {
"browsePrompts": "Prompts durchsuchen"
}
}
}
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

python - <<'PY'
import json
from pathlib import Path

base_path = Path("services/platform/messages/de.json")
variant_path = Path("services/platform/messages/de-AT.json")

base = json.loads(base_path.read_text(encoding="utf-8"))
variant = json.loads(variant_path.read_text(encoding="utf-8"))

def flatten(obj, prefix=""):
    out = {}
    if isinstance(obj, dict):
        for k, v in obj.items():
            p = f"{prefix}.{k}" if prefix else k
            out.update(flatten(v, p))
    else:
        out[prefix] = obj
    return out

b = flatten(base)
v = flatten(variant)

same = [k for k, val in v.items() if k in b and b[k] == val]
diff = [k for k, val in v.items() if k in b and b[k] != val]
only_variant = [k for k in v if k not in b]

print(f"Variant leaf keys: {len(v)}")
print(f"Same as base de.json: {len(same)}")
print(f"Different from base de.json: {len(diff)}")
print(f"Only in de-AT.json: {len(only_variant)}")

if same:
    print("\nSample redundant keys:")
    for k in same[:30]:
        print(" -", k)
PY

Repository: tale-project/tale

Length of output: 1034


Remove or minimize de-AT.json — currently a full duplicate of de.json.

All 41 keys in this file are identical to the base de.json. Per the established pattern, locale variants must contain only keys whose values differ from the base locale. Since there are no Austrian-specific overrides, this file should either be deleted or kept empty to allow fallback to the base German locale.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@services/platform/messages/de-AT.json` around lines 1 - 65, de-AT.json is a
full duplicate of the base German locale (all keys under "prompts" and
"settings" match de.json); remove or minimize it so the app falls back to
de.json: either delete services/platform/messages/de-AT.json entirely or replace
its contents with an empty object or only the specific override keys that differ
(e.g., any unique entries under "prompts" or "settings" if needed) so that only
Austrian-specific overrides remain and all identical keys are omitted.

Comment on lines +42 to 45
},
"form": {
"browsePrompts": "Prompts durchsuchen"
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Fix i18n key nesting for browsePrompts path.

Line 43 currently places form under settings.agents, but the UI expects settings.agents.knowledge.form.browsePrompts. This will miss the translation at runtime.

Proposed fix
-      "knowledge": {
-        "fileTooLarge": "Datei zu gross"
-      },
-      "form": {
-        "browsePrompts": "Prompts durchsuchen"
-      }
+      "knowledge": {
+        "fileTooLarge": "Datei zu gross",
+        "form": {
+          "browsePrompts": "Prompts durchsuchen"
+        }
+      }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@services/platform/messages/de-CH.json` around lines 42 - 45, The current
translation places "form": {"browsePrompts": "..."} under settings.agents, but
the UI expects settings.agents.knowledge.form.browsePrompts; update the JSON
structure so the "browsePrompts" key is nested under the "knowledge" object
(i.e., move or create "knowledge" and put "form": {"browsePrompts": "Prompts
durchsuchen"} inside it) so the translation is available at
settings.agents.knowledge.form.browsePrompts.

"providers": {
"title": "Providers",
"description": "Manage LLM providers and their models",
"description": "Description",
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Find all call sites to confirm whether this key is rendered as a page/section description.
rg -n -C2 --type=ts --type=tsx "settings\.providers\.description|t\(['\"]settings\.providers\.description['\"]\)"

Repository: tale-project/tale

Length of output: 88


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Search for usage of this translation key more broadly
rg -n "settings\.providers\.description|providers\.description" --type=json --type=ts

# Also search for pattern t("settings.providers.description") without type restrictions
rg -n "settings\.providers\.description"

Repository: tale-project/tale

Length of output: 932


🏁 Script executed:

#!/bin/bash

# Read the JSON file around line 1454 to see context
wc -l services/platform/messages/en.json

Repository: tale-project/tale

Length of output: 100


🏁 Script executed:

#!/bin/bash

# Check the context around line 1454
sed -n '1440,1470p' services/platform/messages/en.json

Repository: tale-project/tale

Length of output: 1321


🏁 Script executed:

#!/bin/bash

# Check git log to see what changed in the JSON file around line 1454
git log --oneline -n 20 -- services/platform/messages/en.json

Repository: tale-project/tale

Length of output: 121


🏁 Script executed:

#!/bin/bash

# Check the diff for recent changes to this file
git diff HEAD~5 HEAD -- services/platform/messages/en.json | head -200

Repository: tale-project/tale

Length of output: 89


🏁 Script executed:

#!/bin/bash

# Read the providers-table.tsx context around line 143
sed -n '130,160p' services/platform/app/features/settings/providers/components/providers-table.tsx

Repository: tale-project/tale

Length of output: 923


providers.description is too generic for an empty state message.

The key is used as the description in the empty state of the providers table (providers-table.tsx:143). Currently set to "Description", which is too generic and provides no context to users about what the section does.

Suggested fix
-      "description": "Description",
+      "description": "Manage AI providers and their models.",
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
"description": "Description",
"description": "Manage AI providers and their models.",
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@services/platform/messages/en.json` at line 1454, The "providers.description"
message value is too generic for the providers table empty state; update the
en.json value so it clearly explains the empty state and next steps (e.g.,
mention there are no providers yet and how to add them) so users know what the
section is for; locate the key "providers.description" referenced from
providers-table.tsx (line ~143) and replace "Description" with a concise,
actionable sentence like "No providers yet — add a provider to integrate
external services" (or similar copy that fits tone).

larryro added 2 commits April 11, 2026 16:23
…mpt form

The promptTemplates table was missing from the RLS rules and permission
matrix, causing "insert access not allowed" errors. Additionally, the
prompt form's Team scope option had no team picker, so teamId was always
undefined.
Remove trivially inferred type parameter and mock useTeams in tests.
@larryro larryro merged commit f098bbf into main Apr 11, 2026
24 checks passed
@larryro larryro deleted the feat/issue-1331-wire-prompt-library branch April 11, 2026 08:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Prompt Library feature missing from UI despite changelog claim (v0.2.8)

2 participants