mirror of
https://github.com/mudler/LocalAI.git
synced 2026-11-06 04:23:15 -05:00
feat(ui): one switch per capability in the agent form
The agent form switched the same capability in two places: a Tools switch and a permission at the bottom that changed what the switch meant. Show one switch per capability and put its permissions under it as options, greyed with a reason while the switch is off. The stored data and the API do not change. Triggers, memory and profile changes, files and saved agents each hold their options. Saved agents is one switch: either stored value turns it on, off clears both, and on adds only the group so it never turns off the defaults of the messaging connections. Reply, start new channels and the permissions that apply when nobody is watching have a section each. Every switch and option has one line that says what it lets the model do, and the three trigger switches have names that cannot be mixed up. The Permissions fold is gone: its list is now in Tools. The form names a messaging connection of the agent that does not allow an option the agent holds, with a link to that connection. The chat Tools menu draws the same rows and shows the held options read only. Assisted-by: Claude:claude-sonnet-5-5
This commit is contained in:
42 files changed
+1291
-310
No files matched your search
@@ -39,14 +39,14 @@ test.describe('Agent form', () => {
|
||||
})
|
||||
})
|
||||
|
||||
test('warns when the first permission turns off the messaging defaults, and adds the missing ones in one click', async ({ page }) => {
|
||||
test('warns when the first option turns off the messaging defaults, and adds the missing ones in one click', async ({ page }) => {
|
||||
const s = await installAgents(page)
|
||||
await page.goto('/app/agents/a2/edit')
|
||||
await fold(page, 'Grants').locator('.ag-fold__button').click()
|
||||
await fold(page, 'Tools').locator('.ag-fold__button').click()
|
||||
await expect(page.getByTestId('agent-grants-notice')).toHaveCount(0)
|
||||
await page.getByTestId('agent-grant').filter({ hasText: 'Remember things' }).getByRole('checkbox').check()
|
||||
await page.getByTestId('agent-tools-panel').getByRole('switch', { name: 'Remember things' }).click()
|
||||
const notice = page.getByTestId('agent-grants-notice')
|
||||
await expect(notice).toContainText('triggers.propose, triggers.run, talkback.channels, files.upload')
|
||||
await expect(notice).toContainText('Also propose from messaging apps, Let triggers start from messaging apps, Reply on known channels, Receive files from messaging apps')
|
||||
await page.getByTestId('agent-grants-add-missing').click()
|
||||
await expect(notice).toHaveCount(0)
|
||||
await page.getByRole('button', { name: 'Save changes' }).first().click()
|
||||
@@ -58,11 +58,79 @@ test.describe('Agent form', () => {
|
||||
test('shows no warning for an agent that already had permissions', async ({ page }) => {
|
||||
await installAgents(page, { agents: [{ ...AGENTS[1], builtins: ['memory.write'] }] })
|
||||
await page.goto('/app/agents/a2/edit')
|
||||
await fold(page, 'Grants').locator('.ag-fold__button').click()
|
||||
await page.getByTestId('agent-grant').filter({ hasText: 'Propose triggers' }).getByRole('checkbox').check()
|
||||
await fold(page, 'Tools').locator('.ag-fold__button').click()
|
||||
await page.getByTestId('agent-tools-panel').getByRole('switch', { name: 'Also propose from messaging apps' }).click()
|
||||
await expect(page.getByTestId('agent-grants-notice')).toHaveCount(0)
|
||||
})
|
||||
|
||||
test('each capability is one switch with its options under it, greyed with a reason while the switch is off', async ({ page }) => {
|
||||
const s = await installAgents(page, { agents: [{ ...AGENTS[1], builtins: ['triggers.propose', 'act.files'], builtins_off: ['triggers'] }] })
|
||||
await page.goto('/app/agents/a2/edit')
|
||||
await fold(page, 'Tools').locator('.ag-fold__button').click()
|
||||
const panel = page.getByTestId('agent-tools-panel')
|
||||
// The three trigger switches have names that cannot be mixed up.
|
||||
const triggers = panel.getByRole('switch', { name: 'Create and manage triggers' })
|
||||
await expect(triggers).not.toBeChecked()
|
||||
const propose = panel.getByRole('switch', { name: 'Also propose from messaging apps' })
|
||||
const run = panel.getByRole('switch', { name: 'Let triggers start from messaging apps' })
|
||||
await expect(propose).toBeDisabled()
|
||||
await expect(propose).toBeChecked()
|
||||
await expect(propose).toHaveAccessibleDescription(/Turn on .Create and manage triggers. to use this/)
|
||||
await expect(run).toBeDisabled()
|
||||
await expect(panel.getByRole('group', { name: 'Options of Create and manage triggers' })).toBeVisible()
|
||||
await triggers.click()
|
||||
await expect(propose).toBeEnabled()
|
||||
await run.click()
|
||||
// A grant is listed once: files on its own is under Your files, not in a second place.
|
||||
await expect(panel.getByRole('switch', { name: 'Write files on its own' })).toHaveCount(1)
|
||||
await expect(panel.getByRole('switch', { name: 'Write files on its own' })).toBeChecked()
|
||||
// The permissions that apply with nobody watching have a section of their own.
|
||||
const quiet = panel.getByTestId('agent-tools-group-unattended')
|
||||
await expect(quiet).toContainText('When nobody is watching')
|
||||
await expect(quiet.getByRole('switch')).toHaveCount(3)
|
||||
await expect(quiet.getByTestId('agent-tools-note').first()).toContainText('Sensitive')
|
||||
await page.getByRole('button', { name: 'Save changes' }).first().click()
|
||||
await expect.poll(() => s.calls.find(c => c.method === 'PUT')?.body).toMatchObject({ builtins_off: [], builtins: ['triggers.propose', 'act.files', 'triggers.run'] })
|
||||
})
|
||||
|
||||
test('saved agents is one switch: turning it off takes the grant away too, turning it on adds only the group', async ({ page }) => {
|
||||
const s = await installAgents(page, { agents: [{ ...AGENTS[1], builtins: ['memory.write', 'saved_agents'] }, { ...AGENTS[0], id: 'a9', name: 'plain' }] })
|
||||
await page.goto('/app/agents/a2/edit')
|
||||
await fold(page, 'Tools').locator('.ag-fold__button').click()
|
||||
const sw = page.getByTestId('agent-tools-panel').getByRole('switch', { name: 'Saved agents' })
|
||||
await expect(sw).toBeChecked()
|
||||
await expect(page.getByTestId('agent-tools-panel').getByText('Call your saved agents')).toHaveCount(0)
|
||||
await sw.click()
|
||||
await page.getByRole('button', { name: 'Save changes' }).first().click()
|
||||
await expect.poll(() => s.calls.find(c => c.method === 'PUT')?.body).toMatchObject({ builtins: ['memory.write'], builtins_on: [] })
|
||||
await page.goto('/app/agents/a9/edit')
|
||||
await fold(page, 'Tools').locator('.ag-fold__button').click()
|
||||
await page.getByTestId('agent-tools-panel').getByRole('switch', { name: 'Saved agents' }).click()
|
||||
await page.getByRole('button', { name: 'Save changes' }).first().click()
|
||||
await expect.poll(() => s.calls.filter(c => c.method === 'PUT').at(-1)?.body).toMatchObject({ builtins: [], builtins_on: ['saved_agents'] })
|
||||
})
|
||||
|
||||
test('a messaging connection that does not allow what the agent holds is named under that option, with a link', async ({ page }) => {
|
||||
const bindings = [
|
||||
{ id: 'b1', name: 'Bender', kind: 'slack', agent_id: 'a2', enabled: true, caps: [] },
|
||||
{ id: 'b2', name: 'Other', kind: 'slack', agent_id: 'a1', enabled: true, caps: [] },
|
||||
{ id: 'b3', name: 'Ready', kind: 'slack', agent_id: 'a2', enabled: true, caps: ['triggers.propose'] },
|
||||
]
|
||||
await installAgents(page, { bindings, agents: [{ ...AGENTS[1], builtins: ['triggers.propose', 'memory.write'] }] })
|
||||
await page.goto('/app/agents/a2/edit')
|
||||
await fold(page, 'Tools').locator('.ag-fold__button').click()
|
||||
const panel = page.getByTestId('agent-tools-panel')
|
||||
const notes = panel.getByTestId('agent-tools-conn-note')
|
||||
await expect(notes).toHaveCount(3)
|
||||
const propose = panel.getByTestId('agent-tools-item-box').filter({ has: page.getByRole('switch', { name: 'Also propose from messaging apps' }) }).last()
|
||||
await expect(propose.getByTestId('agent-tools-conn-note')).toHaveCount(1)
|
||||
await expect(propose.getByTestId('agent-tools-conn-note')).toContainText('Slack Bender does not allow this yet.')
|
||||
await expect(propose.getByRole('link', { name: 'Open its permissions' })).toHaveAttribute('href', /\/app\/addons\/slack\/apps\?binding=b1$/)
|
||||
await expect(propose.getByRole('switch', { name: 'Also propose from messaging apps' })).toHaveAccessibleDescription(/does not allow this yet/)
|
||||
await expect(panel).not.toContainText('Slack Other')
|
||||
await expect(propose).not.toContainText('Slack Ready')
|
||||
})
|
||||
|
||||
test('sets the network of the commands of unattended runs', async ({ page }) => {
|
||||
const s = await installAgents(page)
|
||||
await page.goto('/app/agents/new')
|
||||
@@ -137,18 +205,18 @@ test.describe('Agent form', () => {
|
||||
const panel = page.getByTestId('agent-tools-panel')
|
||||
// The same words as the Tools menu of a chat: a title, a description, and
|
||||
// the add-on's declared title instead of its id. Eight rows are the built-in
|
||||
// groups and add-ons; the others are the six grants the agent may hold.
|
||||
// groups and add-ons; the others are the options and permissions under them.
|
||||
const rows = panel.getByTestId('agent-tools-item')
|
||||
await expect(rows).toHaveCount(14)
|
||||
await expect(rows).toHaveCount(22)
|
||||
for (const row of await rows.all()) await expect(row.getByTestId('agent-tools-blurb')).not.toBeEmpty()
|
||||
await expect(panel.getByRole('switch', { name: 'Memory and profile changes' })).toBeChecked()
|
||||
await expect(panel.getByRole('switch', { name: 'Office' })).toBeChecked()
|
||||
await expect(panel).toContainText('Read and write documents and spreadsheets.')
|
||||
await expect(panel.getByRole('switch', { name: 'Saved agents' })).not.toBeChecked()
|
||||
|
||||
await panel.getByRole('switch', { name: 'Triggers', exact: true }).click()
|
||||
await panel.getByRole('switch', { name: 'Create and manage triggers', exact: true }).click()
|
||||
// Once off, the row also says what the model loses.
|
||||
await expect(panel.getByTestId('agent-tools-group-builtins').getByTestId('agent-tools-item').filter({ hasText: 'Triggers' })).toContainText('The model cannot create or manage triggers.')
|
||||
await expect(panel.getByTestId('agent-tools-group-builtins').getByTestId('agent-tools-item').filter({ hasText: 'Create and manage triggers' }).first()).toContainText('The model cannot propose or manage triggers.')
|
||||
await panel.getByRole('switch', { name: 'Saved agents' }).click()
|
||||
await page.getByRole('button', { name: 'Save Changes' }).first().click()
|
||||
await expect.poll(() => s.calls.find(c => c.method === 'PUT')?.body).toMatchObject({ builtins_off: ['triggers'], builtins_on: ['saved_agents'], addons: ['office'] })
|
||||
|
||||
+14
-2
@@ -19,11 +19,20 @@ export const AGENTS = [
|
||||
|
||||
export const GRANTS = [
|
||||
{ name: 'memory.write', title: 'Remember things', description: 'The agent can propose a note in your memory.', sensitive: false },
|
||||
{ name: 'profile.write', title: 'Change its own rules', description: 'The agent can propose an edit to its profile.', sensitive: true },
|
||||
{ name: 'skills.write', title: 'Write skills', description: 'The agent can propose a skill.', sensitive: true },
|
||||
{ name: 'pages.write', title: 'Create pages', description: 'The agent can propose a page.', sensitive: true },
|
||||
{ name: 'dashboard.write', title: 'Change the dashboard', description: 'The agent can propose a dashboard layout.', sensitive: true },
|
||||
{ name: 'triggers.propose', title: 'Propose triggers', description: 'The agent can propose a task that runs by itself.', sensitive: false },
|
||||
{ name: 'triggers.run', title: 'Run triggers', description: 'The triggers of this agent may start from a messaging app.', sensitive: false },
|
||||
{ name: 'talkback.channels', title: 'Reply on known channels', description: 'The agent can send a message to a channel it already talks in.', sensitive: false },
|
||||
{ name: 'talkback.new_channel', title: 'Start new channels', description: 'The agent can start a conversation on a new channel.', sensitive: true },
|
||||
{ name: 'files.upload', title: 'Receive files', description: 'Senders can attach files for the agent to read.', sensitive: false },
|
||||
{ name: 'profile.write', title: 'Change its own rules', description: 'The agent can propose an edit to its profile.', sensitive: true },
|
||||
{ name: 'act.files', title: 'Write files on its own', description: 'A run that nobody watches may write files.', sensitive: true },
|
||||
{ name: 'act.addons', title: 'Use add-on actions on its own', description: 'A run that nobody watches may call add-on actions.', sensitive: true },
|
||||
{ name: 'act.send', title: 'Send messages on its own', description: 'A run that nobody watches may send messages.', sensitive: true },
|
||||
{ name: 'act.spend', title: 'Use paid or external tools on its own', description: 'A run that nobody watches may use paid tools.', sensitive: true },
|
||||
{ name: 'saved_agents', title: 'Call your saved agents', description: 'The agent can start a saved agent.', sensitive: false },
|
||||
]
|
||||
|
||||
const iso = (minutesAgo) => new Date(Date.now() - minutesAgo * 60_000).toISOString()
|
||||
@@ -120,7 +129,7 @@ export const DRAFT_TOOLS = {
|
||||
|
||||
export async function installAgents(page, {
|
||||
agents = AGENTS, chats = CHATS, triggers = TRIGGERS, runs = RUNS, skills = SKILLS, proposals = [], importWarnings = [], files = null,
|
||||
models, collections = ['handbook', 'notes'], connectors = [{ id: 'm1', name: 'Docs', enabled: true }, { id: 'm2', name: 'Parked', enabled: false }],
|
||||
models, collections = ['handbook', 'notes'], bindings = [], connectors = [{ id: 'm1', name: 'Docs', enabled: true }, { id: 'm2', name: 'Parked', enabled: false }],
|
||||
} = {}) {
|
||||
await mockChat(page, { models })
|
||||
const s = {
|
||||
@@ -132,6 +141,9 @@ export async function installAgents(page, {
|
||||
|
||||
await page.route('**/api/collections*', route => route.fulfill({ json: { collections } }))
|
||||
await page.route('**/v1/mcp/servers/*', route => route.fulfill({ json: { model: 'qwen3-8b', servers: [{ name: 'crm' }, { name: 'mail' }] } }))
|
||||
// The messaging connections: the agent form names the ones of this agent.
|
||||
await page.route(/\/api\/chats\/connectors$/, route => route.fulfill({ json: { connectors: bindings } }))
|
||||
await page.route(/\/api\/chats\/connectors\/kinds$/, route => route.fulfill({ json: { kinds: [{ kind: 'slack', addon: 'slack', title: 'Slack' }], capabilities: [] } }))
|
||||
await page.route('**/api/chats/mcp-connectors*', route => route.fulfill({ json: { connectors } }))
|
||||
await page.route('**/api/chats/draft/tools*', route => route.fulfill({
|
||||
json: { ...DRAFT_TOOLS, servers: [], off: [], connectors: connectors.map(c => ({ id: c.id, name: c.name, off: false, usable: c.enabled, reason: c.enabled ? undefined : 'off' })) },
|
||||
|
||||
@@ -44,20 +44,20 @@ test.describe('Chat tools menu: the Triggers group', () => {
|
||||
test('shows a Triggers row with a switch that is on by default', async ({ page }) => {
|
||||
await stub(page)
|
||||
await open(page)
|
||||
const row = page.getByTestId('chat-tools-item').filter({ has: sw(page, 'Triggers') })
|
||||
const row = page.getByTestId('chat-tools-item').filter({ has: sw(page, 'Create and manage triggers') })
|
||||
await expect(row).toHaveCount(1)
|
||||
await expect(sw(page, 'Triggers')).toHaveAttribute('aria-checked', 'true')
|
||||
await expect(sw(page, 'Triggers')).toBeEnabled()
|
||||
await expect(sw(page, 'Create and manage triggers')).toHaveAttribute('aria-checked', 'true')
|
||||
await expect(sw(page, 'Create and manage triggers')).toBeEnabled()
|
||||
})
|
||||
|
||||
test('switching it off sends the group in the off list, and on again clears it', async ({ page }) => {
|
||||
const state = await stub(page)
|
||||
await open(page)
|
||||
await sw(page, 'Triggers').click()
|
||||
await expect(sw(page, 'Triggers')).toHaveAttribute('aria-checked', 'false')
|
||||
await sw(page, 'Create and manage triggers').click()
|
||||
await expect(sw(page, 'Create and manage triggers')).toHaveAttribute('aria-checked', 'false')
|
||||
await expect.poll(() => state.puts).toEqual([{ off: ['triggers'] }])
|
||||
await sw(page, 'Triggers').click()
|
||||
await expect(sw(page, 'Triggers')).toHaveAttribute('aria-checked', 'true')
|
||||
await sw(page, 'Create and manage triggers').click()
|
||||
await expect(sw(page, 'Create and manage triggers')).toHaveAttribute('aria-checked', 'true')
|
||||
await expect.poll(() => state.puts).toEqual([{ off: ['triggers'] }, { off: [] }])
|
||||
})
|
||||
|
||||
@@ -65,11 +65,11 @@ test.describe('Chat tools menu: the Triggers group', () => {
|
||||
const state = await stub(page)
|
||||
await open(page)
|
||||
await page.getByTestId('chat-tools-none').click()
|
||||
await expect(sw(page, 'Triggers')).toHaveAttribute('aria-checked', 'false')
|
||||
await expect(sw(page, 'Create and manage triggers')).toHaveAttribute('aria-checked', 'false')
|
||||
await expect(sw(page, 'Look things up online')).toHaveAttribute('aria-checked', 'false')
|
||||
await expect.poll(() => state.puts).toEqual([{ off: ['triggers', 'web'] }])
|
||||
await page.getByTestId('chat-tools-all').click()
|
||||
await expect(sw(page, 'Triggers')).toHaveAttribute('aria-checked', 'true')
|
||||
await expect(sw(page, 'Create and manage triggers')).toHaveAttribute('aria-checked', 'true')
|
||||
await expect.poll(() => state.puts.at(-1)).toEqual({ off: [] })
|
||||
})
|
||||
|
||||
@@ -77,8 +77,8 @@ test.describe('Chat tools menu: the Triggers group', () => {
|
||||
const reason = 'a run that started by itself cannot set triggers'
|
||||
await stub(page, { triggers: { usable: false, reason } })
|
||||
await open(page)
|
||||
await expect(sw(page, 'Triggers')).toBeDisabled()
|
||||
await expect(sw(page, 'Triggers')).toHaveAccessibleDescription(reason)
|
||||
await expect(sw(page, 'Triggers')).toHaveAttribute('aria-checked', 'false')
|
||||
await expect(sw(page, 'Create and manage triggers')).toBeDisabled()
|
||||
await expect(sw(page, 'Create and manage triggers')).toHaveAccessibleDescription(reason)
|
||||
await expect(sw(page, 'Create and manage triggers')).toHaveAttribute('aria-checked', 'false')
|
||||
})
|
||||
})
|
||||
@@ -765,7 +765,7 @@ test.describe('Chat tools menu: every group of built-in tools', () => {
|
||||
await stubGroups(page)
|
||||
await open(page)
|
||||
const names = await page.getByTestId('chat-tools-group-builtins').locator('.swl-row__name').allTextContents()
|
||||
expect(names).toEqual(['Run commands', 'Your files', 'Look things up online', 'Images and audio', 'Collections', 'Sub-agents', 'Triggers'])
|
||||
expect(names).toEqual(['Run commands', 'Your files', 'Look things up online', 'Images and audio', 'Collections', 'Sub-agents', 'Create and manage triggers'])
|
||||
await expect(row(page, 'Run commands').getByTestId('chat-tools-note')).toHaveText(['Served by add-on sandbox', 'Commands run isolated'])
|
||||
await expect(row(page, 'Your files')).toHaveAttribute('title', 'list_files, read_file, write_file · built-in')
|
||||
await expect(sw(page, 'Collections')).toBeDisabled()
|
||||
|
||||
@@ -81,8 +81,7 @@
|
||||
"MCP": "MCP servers",
|
||||
"export": "Export",
|
||||
"Files": "Dateien",
|
||||
"Tools": "Werkzeuge",
|
||||
"Grants": "Permissions"
|
||||
"Tools": "Werkzeuge"
|
||||
},
|
||||
"name": "Name",
|
||||
"description": "Description",
|
||||
@@ -137,17 +136,19 @@
|
||||
"all": "Alle öffentlichen Seiten"
|
||||
},
|
||||
"toolsSummary": "{{on}} von {{total}} an",
|
||||
"toolsHelp": "Wähle, was ein Chat mit diesem Agenten nutzen kann. Das sind dieselben Schalter wie im Werkzeuge-Menü eines Chats. Ein ausgeschaltetes Werkzeug wird dem Modell nie angeboten, und ein Chat mit diesem Agenten kann es nicht einschalten.",
|
||||
"toolsHelp": "Wähle, was ein Chat mit diesem Agenten nutzen kann. Das sind dieselben Schalter wie im Werkzeug-Menü eines Chats, mit den Optionen eines Schalters darunter. Ein ausgeschaltetes Werkzeug wird dem Modell nie angeboten. Ohne angekreuzte Option behält der Agent die Standardwerte seiner Messaging-Verbindungen; sobald du eine ankreuzt, wirken nur die angekreuzten.",
|
||||
"toolsHeading": "Werkzeuge dieses Agenten",
|
||||
"skillsLater": "Ein Chat mit diesem Agenten liest nur die eingeschalteten Skills.",
|
||||
"skillsHeading": "Skills dieses Agenten",
|
||||
"grantsHelp": "What the agent may do beyond its tools. With no permission ticked, the agent keeps the defaults it had before permissions existed. Once you tick any, only the ticked ones work.",
|
||||
"grantsDefault": "Defaults",
|
||||
"countGrants": "{{count}} granted",
|
||||
"grantSensitive": "needs care",
|
||||
"grantsNoticeTitle": "Some messaging features will turn off.",
|
||||
"grantsNotice": "This agent had no permission list, so it kept these on its messaging connections: {{grants}}. They stop working until you tick them here.",
|
||||
"grantsAddMissing": "Add the missing permissions"
|
||||
"grantsAddMissing": "Add the missing permissions",
|
||||
"grantNames": {
|
||||
"triggers_propose": "Auch aus Messaging-Apps vorschlagen",
|
||||
"triggers_run": "Trigger aus Messaging-Apps starten lassen",
|
||||
"talkback_channels": "Auf bekannten Kanälen antworten",
|
||||
"files_upload": "Dateien aus Messaging-Apps empfangen"
|
||||
}
|
||||
},
|
||||
"run": {
|
||||
"workingLine": "Working"
|
||||
|
||||
@@ -138,7 +138,8 @@
|
||||
"failed": "Nicht gespeichert. Der Schalter steht wieder wie vorher.",
|
||||
"unavailable": "In diesem Chat nicht verfügbar",
|
||||
"toolCount_one": "{{count}} Werkzeug",
|
||||
"toolCount_other": "{{count}} Werkzeuge"
|
||||
"toolCount_other": "{{count}} Werkzeuge",
|
||||
"optionsOf": "Optionen von {{name}}"
|
||||
},
|
||||
"skills": {
|
||||
"label": "Skills",
|
||||
|
||||
@@ -314,7 +314,7 @@
|
||||
"builtin": {
|
||||
"web": "Web",
|
||||
"saved_agents": "Gespeicherte Agenten",
|
||||
"triggers": "Trigger",
|
||||
"triggers": "Trigger erstellen und verwalten",
|
||||
"shell": "Befehle ausführen",
|
||||
"files": "Deine Dateien",
|
||||
"media": "Bilder und Audio",
|
||||
@@ -334,15 +334,15 @@
|
||||
"isolated": "Befehle laufen isoliert"
|
||||
},
|
||||
"describe": {
|
||||
"shell": "Das Modell kann Shell-Befehle und Skripte ausführen. Sie laufen in einem Add-on, das sie isoliert, wenn eines installiert ist, sonst direkt auf diesem Rechner.",
|
||||
"files": "Das Modell kann deine Dateien auflisten, lesen, schreiben, bearbeiten, verschieben, löschen und durchsuchen und Dokumente lesen. Ein Chat eines Agenten, der in einem Ordner arbeitet, erreicht nur diesen Ordner.",
|
||||
"web": "Das Modell kann im Internet suchen und eine öffentliche Seite über ihre Adresse lesen. Adressen in deinem Netzwerk werden abgelehnt, außer ein Administrator erlaubt sie.",
|
||||
"media": "Das Modell kann ein Bild beschreiben oder eine Aufnahme aus deinen Dateien mit einem Hilfsmodell transkribieren.",
|
||||
"collections": "Das Modell kann deine Sammlungen auflisten und darin nach den Passagen suchen, die zu einer Frage passen.",
|
||||
"subagents": "Das Modell kann einen Sub-Agenten starten, der mit denselben Schaltern wie dieser Chat an einer Aufgabe arbeitet und Bericht erstattet.",
|
||||
"saved_agents": "Das Modell kann deine gespeicherten Agenten auflisten und einen als Sub-Agenten starten, mit dessen eigenen Anweisungen und Modell.",
|
||||
"triggers": "Das Modell kann Trigger vorschlagen, auflisten, ändern und löschen: Aufgaben, die von selbst zu einer festen Zeit oder beim Eintreffen einer Datei in einem Ordner laufen. Ein neuer Trigger oder eine Änderung wartet auf einer Karte im Chat, bis du sie bestätigst; Pausieren oder Fortsetzen gilt sofort und lässt sich rückgängig machen.",
|
||||
"changes": "Das Modell kann eine Änderung an deinen Gedächtnisnotizen oder an den festen Regeln eines Agenten vorschlagen und eine bestätigte Änderung rückgängig machen. Nichts ändert sich, bis du den Vorschlag auf einer Karte im Chat bestätigst."
|
||||
"shell": "Das Modell kann Shell-Befehle und Skripte ausführen.",
|
||||
"files": "Das Modell kann deine Dateien auflisten, lesen, schreiben und durchsuchen.",
|
||||
"web": "Das Modell kann im Internet suchen und öffentliche Seiten lesen.",
|
||||
"media": "Das Modell kann Bilder beschreiben und Aufnahmen aus deinen Dateien transkribieren.",
|
||||
"collections": "Das Modell kann deine Sammlungen durchsuchen.",
|
||||
"subagents": "Das Modell kann für eine Aufgabe einen Sub-Agenten starten und dessen Bericht erhalten.",
|
||||
"saved_agents": "Das Modell kann einen deiner gespeicherten Agenten als Sub-Agenten starten.",
|
||||
"triggers": "Das Modell kann Trigger vorschlagen, auflisten, ändern und löschen. Du bestätigst jeden neuen Trigger und jede Änderung.",
|
||||
"changes": "Das Modell kann Änderungen an deinem Gedächtnis und an den Dateien eines Agenten vorschlagen. Du bestätigst jede einzelne."
|
||||
},
|
||||
"whenOff": {
|
||||
"shell": "Das Modell kann Dateien schreiben, aber nichts ausführen.",
|
||||
@@ -352,7 +352,7 @@
|
||||
"collections": "Das Modell kann deine Sammlungen nicht lesen.",
|
||||
"subagents": "Das Modell arbeitet allein.",
|
||||
"saved_agents": "Das Modell kann deine gespeicherten Agenten weder sehen noch starten.",
|
||||
"triggers": "Das Modell kann keine Trigger erstellen oder verwalten. Ein Lauf, den ein Trigger oder ein Connector gestartet hat, hat sie nie.",
|
||||
"triggers": "Das Modell kann keine Trigger vorschlagen oder verwalten.",
|
||||
"changes": "Das Modell kann keine Änderungen an deinem Gedächtnis oder an den Regeln eines Agenten vorschlagen."
|
||||
},
|
||||
"addonDescribe_one": "Gibt dem Modell {{count}} Werkzeug dieses Add-ons.",
|
||||
@@ -360,7 +360,7 @@
|
||||
"serverDescribe": "Ein MCP-Server des Modells: Seine Werkzeuge werden dem Modell angeboten.",
|
||||
"connectorDescribe": "Einer deiner MCP-Connectors: Seine Werkzeuge werden dem Modell angeboten.",
|
||||
"gone": "Hier nicht mehr verfügbar. Schalte es aus, um es zu entfernen.",
|
||||
"grants": "Was der Agent ändern darf",
|
||||
"grants": "Weitere Berechtigungen",
|
||||
"grantSensitive": "Sensibel: Das ändert, was der Agent später tun oder erreichen darf.",
|
||||
"connection": {
|
||||
"label": "Verbindungen",
|
||||
@@ -374,6 +374,77 @@
|
||||
"agentLabel": "Verbindungen für Chats dieses Agenten",
|
||||
"agentHelp": "Chats dieses Agenten dürfen nur diese Verbindungen nutzen und können sie nicht ändern.",
|
||||
"perChatHelp": "Keine gewählt: Jeder Chat wählt selbst."
|
||||
},
|
||||
"optionNeeds": "Schalte „{{name}}“ ein, um dies zu nutzen.",
|
||||
"connectionMissing": "{{name}} erlaubt das noch nicht.",
|
||||
"connectionOpen": "Berechtigungen öffnen",
|
||||
"section": {
|
||||
"messaging": {
|
||||
"title": "Messaging-Apps",
|
||||
"intro": "Das gilt für Chats, die in einer Messaging-App beginnen. Die Verbindung muss dasselbe auf ihrer eigenen Berechtigungsseite erlauben."
|
||||
},
|
||||
"unattended": {
|
||||
"title": "Wenn niemand zusieht",
|
||||
"intro": "Das gilt für Läufe, die ein Trigger oder eine Messaging-App startet und bei denen niemand einen Schritt bestätigen kann."
|
||||
}
|
||||
},
|
||||
"grant": {
|
||||
"memory_write": {
|
||||
"title": "Dinge merken",
|
||||
"description": "Das Modell kann eine Notiz für dein Gedächtnis oder das des Agenten vorschlagen. Du bestätigst jede Notiz."
|
||||
},
|
||||
"profile_write": {
|
||||
"title": "Eigene Regeln ändern",
|
||||
"description": "Das Modell kann eine Änderung der festen Regeln des Agenten vorschlagen. Du bestätigst jede Änderung."
|
||||
},
|
||||
"skills_write": {
|
||||
"title": "Skills schreiben",
|
||||
"description": "Das Modell kann einen neuen oder geänderten Skill vorschlagen. Du bestätigst jeden einzelnen."
|
||||
},
|
||||
"pages_write": {
|
||||
"title": "Seiten erstellen",
|
||||
"description": "Das Modell kann eine kleine App vorschlagen, die in einem isolierten Frame läuft. Du bestätigst sie."
|
||||
},
|
||||
"dashboard_write": {
|
||||
"title": "Dashboard ändern",
|
||||
"description": "Das Modell kann ein neues Layout für dein Home-Dashboard vorschlagen. Du bestätigst jede Änderung."
|
||||
},
|
||||
"triggers_propose": {
|
||||
"title": "Auch aus Messaging-Apps vorschlagen",
|
||||
"description": "Das Modell kann einen Trigger vorschlagen, wenn jemand in einer Messaging-App danach fragt. Du bestätigst ihn."
|
||||
},
|
||||
"triggers_run": {
|
||||
"title": "Trigger aus Messaging-Apps starten lassen",
|
||||
"description": "Ein Trigger, der an eine Messaging-Verbindung gebunden ist, kann einen Lauf starten und das Ergebnis dort zustellen."
|
||||
},
|
||||
"talkback_channels": {
|
||||
"title": "Auf bekannten Kanälen antworten",
|
||||
"description": "Das Modell kann eine Nachricht an einen Kanal senden, in dem es schon schreibt."
|
||||
},
|
||||
"talkback_new_channel": {
|
||||
"title": "Neue Kanäle starten",
|
||||
"description": "Das Modell kann ein Gespräch in einem Kanal beginnen, den es noch nicht genutzt hat."
|
||||
},
|
||||
"files_upload": {
|
||||
"title": "Dateien aus Messaging-Apps empfangen",
|
||||
"description": "Absender können Dateien anhängen, die das Modell liest. Es kann keine Dateien versenden."
|
||||
},
|
||||
"act_files": {
|
||||
"title": "Selbstständig Dateien schreiben",
|
||||
"description": "Ein Lauf, den niemand beobachtet, kann Dateien in den Ordnern des Agenten schreiben."
|
||||
},
|
||||
"act_addons": {
|
||||
"title": "Add-on-Aktionen selbstständig nutzen",
|
||||
"description": "Ein Lauf, den niemand beobachtet, kann die Aktionen der Add-ons des Agenten aufrufen."
|
||||
},
|
||||
"act_send": {
|
||||
"title": "Selbstständig Nachrichten senden",
|
||||
"description": "Ein Lauf, den niemand beobachtet, kann Nachrichten über sein Zustellziel hinaus senden."
|
||||
},
|
||||
"act_spend": {
|
||||
"title": "Kostenpflichtige oder externe Werkzeuge selbstständig nutzen",
|
||||
"description": "Ein Lauf, den niemand beobachtet, kann kostenpflichtige oder externe Werkzeuge und das Netzwerk nutzen."
|
||||
}
|
||||
}
|
||||
},
|
||||
"vision": {
|
||||
|
||||
@@ -190,13 +190,8 @@
|
||||
"MCP": "MCP servers",
|
||||
"export": "Export",
|
||||
"Files": "Files",
|
||||
"Tools": "Tools",
|
||||
"Grants": "Permissions"
|
||||
"Tools": "Tools"
|
||||
},
|
||||
"grantsHelp": "What the agent may do beyond its tools. With no permission ticked, the agent keeps the defaults it had before permissions existed. Once you tick any, only the ticked ones work.",
|
||||
"grantsDefault": "Defaults",
|
||||
"countGrants": "{{count}} granted",
|
||||
"grantSensitive": "needs care",
|
||||
"grantsNoticeTitle": "Some messaging features will turn off.",
|
||||
"grantsNotice": "This agent had no permission list, so it kept these on its messaging connections: {{grants}}. They stop working until you tick them here.",
|
||||
"grantsAddMissing": "Add the missing permissions",
|
||||
@@ -247,10 +242,16 @@
|
||||
"all": "All public sites"
|
||||
},
|
||||
"toolsSummary": "{{on}} of {{total}} on",
|
||||
"toolsHelp": "Choose what a chat with this agent can use. These are the same switches as the Tools menu of a chat. A tool that is off is never offered to the model, and a chat with this agent cannot switch it on.",
|
||||
"toolsHelp": "Choose what a chat with this agent can use. These are the same switches as the Tools menu of a chat, with the options of a switch under it. A tool that is off is never offered to the model. With no option ticked, the agent keeps the defaults it had on its messaging connections; once you tick any, only the ticked ones work.",
|
||||
"toolsHeading": "Tools of this agent",
|
||||
"skillsLater": "A chat with this agent reads only the skills that are on.",
|
||||
"skillsHeading": "Skills of this agent"
|
||||
"skillsHeading": "Skills of this agent",
|
||||
"grantNames": {
|
||||
"triggers_propose": "Also propose from messaging apps",
|
||||
"triggers_run": "Let triggers start from messaging apps",
|
||||
"talkback_channels": "Reply on known channels",
|
||||
"files_upload": "Receive files from messaging apps"
|
||||
}
|
||||
},
|
||||
"status": {
|
||||
"title": "Status",
|
||||
|
||||
@@ -409,7 +409,8 @@
|
||||
"failed": "Could not save. The switch is back as it was.",
|
||||
"unavailable": "Not available in this chat",
|
||||
"toolCount_one": "{{count}} tool",
|
||||
"toolCount_other": "{{count}} tools"
|
||||
"toolCount_other": "{{count}} tools",
|
||||
"optionsOf": "Options of {{name}}"
|
||||
},
|
||||
"skills": {
|
||||
"label": "Skills",
|
||||
|
||||
@@ -365,12 +365,12 @@
|
||||
"tools": {
|
||||
"summary": "Tools ({{on}} of {{total}} on)",
|
||||
"builtins": "Built-in tools",
|
||||
"grants": "What the agent may change",
|
||||
"grants": "Other permissions",
|
||||
"grantSensitive": "Sensitive: this changes what the agent may do or reach later.",
|
||||
"builtin": {
|
||||
"web": "Look things up online",
|
||||
"saved_agents": "Saved agents",
|
||||
"triggers": "Triggers",
|
||||
"triggers": "Create and manage triggers",
|
||||
"shell": "Run commands",
|
||||
"files": "Your files",
|
||||
"media": "Images and audio",
|
||||
@@ -436,15 +436,15 @@
|
||||
"isolated": "Commands run isolated"
|
||||
},
|
||||
"describe": {
|
||||
"shell": "The model can run shell commands and scripts. They run in an add-on that isolates them when one is installed, otherwise directly on this machine.",
|
||||
"files": "The model can list, read, write, edit, move, delete and search your files, and read documents. A chat of an agent that works in one folder reaches only that folder.",
|
||||
"web": "The model can search the web and read a public page by its address. Addresses inside your network are refused unless an administrator allows them.",
|
||||
"media": "The model can describe an image or transcribe a recording from your files with a helper model.",
|
||||
"collections": "The model can list your collections and search them for the passages that match a question.",
|
||||
"subagents": "The model can start a sub-agent that works on one task with the same switches as this chat and reports back.",
|
||||
"saved_agents": "The model can list your saved agents and start one as a sub-agent, with that agent's own instructions and model.",
|
||||
"triggers": "The model can propose, list, change and delete triggers: tasks that run by themselves at a set time or when a file arrives in a folder. A new trigger or a change waits on a card in the chat until you confirm it; pausing or resuming a trigger applies at once and you can undo it.",
|
||||
"changes": "The model can propose an edit to your memory notes or to an agent's standing rules, and undo an edit you confirmed. Nothing changes until you confirm the proposal on a card in the chat."
|
||||
"shell": "Lets the model run shell commands and scripts.",
|
||||
"files": "Lets the model list, read, write and search your files.",
|
||||
"web": "Lets the model search the web and read public pages.",
|
||||
"media": "Lets the model describe images and transcribe recordings from your files.",
|
||||
"collections": "Lets the model search your collections.",
|
||||
"subagents": "Lets the model start a sub-agent for one task and get its report.",
|
||||
"saved_agents": "Lets the model start one of your saved agents as a sub-agent.",
|
||||
"triggers": "Lets the model propose, list, change and delete triggers. You confirm each new trigger or change.",
|
||||
"changes": "Lets the model propose changes to your memory and to an agent's files. You confirm each one."
|
||||
},
|
||||
"whenOff": {
|
||||
"shell": "The model can write files but cannot run anything.",
|
||||
@@ -454,7 +454,7 @@
|
||||
"collections": "The model cannot read your collections.",
|
||||
"subagents": "The model works alone.",
|
||||
"saved_agents": "The model cannot see or start your saved agents.",
|
||||
"triggers": "The model cannot create or manage triggers. A run that a trigger or a connector started never has them.",
|
||||
"triggers": "The model cannot propose or manage triggers.",
|
||||
"changes": "The model cannot propose edits to your memory or to an agent's rules."
|
||||
},
|
||||
"addonDescribe_one": "Gives the model {{count}} tool from this add-on.",
|
||||
@@ -474,6 +474,77 @@
|
||||
"agentLabel": "Connections for chats of this agent",
|
||||
"agentHelp": "Chats of this agent may use only these connections and cannot change them.",
|
||||
"perChatHelp": "None chosen: each chat chooses its own."
|
||||
},
|
||||
"optionNeeds": "Turn on “{{name}}” to use this.",
|
||||
"connectionMissing": "{{name}} does not allow this yet.",
|
||||
"connectionOpen": "Open its permissions",
|
||||
"section": {
|
||||
"messaging": {
|
||||
"title": "Messaging apps",
|
||||
"intro": "These apply to chats that start in a messaging app. The connection must allow the same thing on its own permissions page."
|
||||
},
|
||||
"unattended": {
|
||||
"title": "When nobody is watching",
|
||||
"intro": "These apply to runs that a trigger or a messaging app starts, where nobody can confirm a step."
|
||||
}
|
||||
},
|
||||
"grant": {
|
||||
"memory_write": {
|
||||
"title": "Remember things",
|
||||
"description": "Lets the model propose a note for your memory or the agent's own. You confirm each note."
|
||||
},
|
||||
"profile_write": {
|
||||
"title": "Change its own rules",
|
||||
"description": "Lets the model propose an edit to the agent's standing rules. You confirm each edit."
|
||||
},
|
||||
"skills_write": {
|
||||
"title": "Write skills",
|
||||
"description": "Lets the model propose a new or changed skill. You confirm each one."
|
||||
},
|
||||
"pages_write": {
|
||||
"title": "Create pages",
|
||||
"description": "Lets the model propose a small app that opens in a sandboxed frame. You confirm it."
|
||||
},
|
||||
"dashboard_write": {
|
||||
"title": "Change the dashboard",
|
||||
"description": "Lets the model propose a new layout for your Home dashboard. You confirm each change."
|
||||
},
|
||||
"triggers_propose": {
|
||||
"title": "Also propose from messaging apps",
|
||||
"description": "Lets the model propose a trigger when someone asks in a messaging app. You confirm it."
|
||||
},
|
||||
"triggers_run": {
|
||||
"title": "Let triggers start from messaging apps",
|
||||
"description": "Lets a trigger tied to a messaging connection start a run and deliver its result there."
|
||||
},
|
||||
"talkback_channels": {
|
||||
"title": "Reply on known channels",
|
||||
"description": "Lets the model send a message to a channel it already talks in."
|
||||
},
|
||||
"talkback_new_channel": {
|
||||
"title": "Start new channels",
|
||||
"description": "Lets the model start a conversation on a channel it has not used before."
|
||||
},
|
||||
"files_upload": {
|
||||
"title": "Receive files from messaging apps",
|
||||
"description": "Lets senders attach files for the model to read. It cannot send files out."
|
||||
},
|
||||
"act_files": {
|
||||
"title": "Write files on its own",
|
||||
"description": "Lets a run nobody is watching write files in the agent's folders."
|
||||
},
|
||||
"act_addons": {
|
||||
"title": "Use add-on actions on its own",
|
||||
"description": "Lets a run nobody is watching call the actions of the agent's add-ons."
|
||||
},
|
||||
"act_send": {
|
||||
"title": "Send messages on its own",
|
||||
"description": "Lets a run nobody is watching send messages beyond its delivery target."
|
||||
},
|
||||
"act_spend": {
|
||||
"title": "Use paid or external tools on its own",
|
||||
"description": "Lets a run nobody is watching use paid or external tools and the network."
|
||||
}
|
||||
}
|
||||
},
|
||||
"mcpPage": {
|
||||
|
||||
@@ -81,8 +81,7 @@
|
||||
"MCP": "MCP servers",
|
||||
"export": "Export",
|
||||
"Files": "Archivos",
|
||||
"Tools": "Herramientas",
|
||||
"Grants": "Permissions"
|
||||
"Tools": "Herramientas"
|
||||
},
|
||||
"name": "Name",
|
||||
"description": "Description",
|
||||
@@ -137,17 +136,19 @@
|
||||
"all": "Todos los sitios públicos"
|
||||
},
|
||||
"toolsSummary": "{{on}} de {{total}} activas",
|
||||
"toolsHelp": "Elige qué puede usar un chat con este agente. Son los mismos interruptores que el menú Herramientas de un chat. Una herramienta apagada nunca se ofrece al modelo, y un chat con este agente no puede encenderla.",
|
||||
"toolsHelp": "Elige qué puede usar un chat con este agente. Son los mismos interruptores que el menú Herramientas de un chat, con las opciones de cada interruptor debajo. Una herramienta desactivada nunca se ofrece al modelo. Sin ninguna opción marcada, el agente conserva los valores por defecto de sus conexiones de mensajería; al marcar alguna, solo funcionan las marcadas.",
|
||||
"toolsHeading": "Herramientas de este agente",
|
||||
"skillsLater": "Un chat con este agente solo lee las skills activas.",
|
||||
"skillsHeading": "Skills de este agente",
|
||||
"grantsHelp": "What the agent may do beyond its tools. With no permission ticked, the agent keeps the defaults it had before permissions existed. Once you tick any, only the ticked ones work.",
|
||||
"grantsDefault": "Defaults",
|
||||
"countGrants": "{{count}} granted",
|
||||
"grantSensitive": "needs care",
|
||||
"grantsNoticeTitle": "Some messaging features will turn off.",
|
||||
"grantsNotice": "This agent had no permission list, so it kept these on its messaging connections: {{grants}}. They stop working until you tick them here.",
|
||||
"grantsAddMissing": "Add the missing permissions"
|
||||
"grantsAddMissing": "Add the missing permissions",
|
||||
"grantNames": {
|
||||
"triggers_propose": "Proponer también desde aplicaciones de mensajería",
|
||||
"triggers_run": "Dejar que los disparadores empiecen desde aplicaciones de mensajería",
|
||||
"talkback_channels": "Responder en canales conocidos",
|
||||
"files_upload": "Recibir archivos de aplicaciones de mensajería"
|
||||
}
|
||||
},
|
||||
"run": {
|
||||
"workingLine": "Working"
|
||||
|
||||
@@ -138,7 +138,8 @@
|
||||
"failed": "No se pudo guardar. El interruptor vuelve a como estaba.",
|
||||
"unavailable": "No disponible en este chat",
|
||||
"toolCount_one": "{{count}} herramienta",
|
||||
"toolCount_other": "{{count}} herramientas"
|
||||
"toolCount_other": "{{count}} herramientas",
|
||||
"optionsOf": "Opciones de {{name}}"
|
||||
},
|
||||
"skills": {
|
||||
"label": "Habilidades",
|
||||
|
||||
@@ -314,7 +314,7 @@
|
||||
"builtin": {
|
||||
"web": "Web",
|
||||
"saved_agents": "Agentes guardados",
|
||||
"triggers": "Disparadores",
|
||||
"triggers": "Crear y gestionar disparadores",
|
||||
"shell": "Ejecutar comandos",
|
||||
"files": "Tus archivos",
|
||||
"media": "Imágenes y audio",
|
||||
@@ -334,15 +334,15 @@
|
||||
"isolated": "Los comandos se ejecutan aislados"
|
||||
},
|
||||
"describe": {
|
||||
"shell": "El modelo puede ejecutar comandos de shell y scripts. Se ejecutan en un add-on que los aísla, si hay uno instalado; si no, directamente en esta máquina.",
|
||||
"files": "El modelo puede listar, leer, escribir, editar, mover, borrar y buscar tus archivos, y leer documentos. Un chat de un agente que trabaja en una sola carpeta solo llega a esa carpeta.",
|
||||
"web": "El modelo puede buscar en la web y leer una página pública por su dirección. Las direcciones dentro de tu red se rechazan salvo que un administrador las permita.",
|
||||
"media": "El modelo puede describir una imagen o transcribir una grabación de tus archivos con un modelo auxiliar.",
|
||||
"collections": "El modelo puede listar tus colecciones y buscar en ellas los pasajes que responden a una pregunta.",
|
||||
"subagents": "El modelo puede iniciar un subagente que trabaja en una tarea con los mismos interruptores que este chat y luego informa.",
|
||||
"saved_agents": "El modelo puede listar tus agentes guardados e iniciar uno como subagente, con las instrucciones y el modelo de ese agente.",
|
||||
"triggers": "El modelo puede proponer, listar, cambiar y borrar disparadores: tareas que se ejecutan solas a una hora fijada o cuando llega un archivo a una carpeta. Un disparador nuevo o un cambio espera en una tarjeta del chat hasta que lo confirmes; pausar o reanudar un disparador se aplica al instante y puedes deshacerlo.",
|
||||
"changes": "El modelo puede proponer un cambio en tus notas de memoria o en las reglas fijas de un agente, y deshacer un cambio que confirmaste. Nada cambia hasta que confirmes la propuesta en una tarjeta del chat."
|
||||
"shell": "El modelo puede ejecutar comandos de shell y scripts.",
|
||||
"files": "El modelo puede listar, leer, escribir y buscar en tus archivos.",
|
||||
"web": "El modelo puede buscar en la web y leer páginas públicas.",
|
||||
"media": "El modelo puede describir imágenes y transcribir grabaciones de tus archivos.",
|
||||
"collections": "El modelo puede buscar en tus colecciones.",
|
||||
"subagents": "El modelo puede iniciar un subagente para una tarea y recibir su informe.",
|
||||
"saved_agents": "El modelo puede iniciar uno de tus agentes guardados como subagente.",
|
||||
"triggers": "El modelo puede proponer, listar, cambiar y borrar disparadores. Tú confirmas cada disparador nuevo o cambio.",
|
||||
"changes": "El modelo puede proponer cambios en tu memoria y en los archivos de un agente. Tú confirmas cada uno."
|
||||
},
|
||||
"whenOff": {
|
||||
"shell": "El modelo puede escribir archivos pero no puede ejecutar nada.",
|
||||
@@ -352,7 +352,7 @@
|
||||
"collections": "El modelo no puede leer tus colecciones.",
|
||||
"subagents": "El modelo trabaja solo.",
|
||||
"saved_agents": "El modelo no puede ver ni iniciar tus agentes guardados.",
|
||||
"triggers": "El modelo no puede crear ni gestionar disparadores. Una ejecución iniciada por un disparador o un conector nunca los tiene.",
|
||||
"triggers": "El modelo no puede proponer ni gestionar disparadores.",
|
||||
"changes": "El modelo no puede proponer cambios en tu memoria ni en las reglas de un agente."
|
||||
},
|
||||
"addonDescribe_one": "Da al modelo {{count}} herramienta de este add-on.",
|
||||
@@ -360,7 +360,7 @@
|
||||
"serverDescribe": "Un servidor MCP del modelo: sus herramientas se ofrecen al modelo.",
|
||||
"connectorDescribe": "Uno de tus conectores MCP: sus herramientas se ofrecen al modelo.",
|
||||
"gone": "Ya no está disponible aquí. Apágalo para quitarlo.",
|
||||
"grants": "Lo que el agente puede cambiar",
|
||||
"grants": "Otros permisos",
|
||||
"grantSensitive": "Sensible: esto cambia lo que el agente podrá hacer o alcanzar más adelante.",
|
||||
"connection": {
|
||||
"label": "Conexiones",
|
||||
@@ -374,6 +374,77 @@
|
||||
"agentLabel": "Conexiones para los chats de este agente",
|
||||
"agentHelp": "Los chats de este agente solo pueden usar estas conexiones y no pueden cambiarlas.",
|
||||
"perChatHelp": "Ninguna elegida: cada chat elige la suya."
|
||||
},
|
||||
"optionNeeds": "Activa «{{name}}» para usar esto.",
|
||||
"connectionMissing": "{{name}} aún no lo permite.",
|
||||
"connectionOpen": "Abrir sus permisos",
|
||||
"section": {
|
||||
"messaging": {
|
||||
"title": "Aplicaciones de mensajería",
|
||||
"intro": "Esto se aplica a los chats que empiezan en una aplicación de mensajería. La conexión debe permitir lo mismo en su propia página de permisos."
|
||||
},
|
||||
"unattended": {
|
||||
"title": "Cuando nadie mira",
|
||||
"intro": "Esto se aplica a las ejecuciones que inicia un disparador o una aplicación de mensajería, donde nadie puede confirmar un paso."
|
||||
}
|
||||
},
|
||||
"grant": {
|
||||
"memory_write": {
|
||||
"title": "Recordar cosas",
|
||||
"description": "El modelo puede proponer una nota para tu memoria o la del agente. Tú confirmas cada nota."
|
||||
},
|
||||
"profile_write": {
|
||||
"title": "Cambiar sus propias reglas",
|
||||
"description": "El modelo puede proponer una edición de las reglas permanentes del agente. Tú confirmas cada edición."
|
||||
},
|
||||
"skills_write": {
|
||||
"title": "Escribir skills",
|
||||
"description": "El modelo puede proponer una skill nueva o modificada. Tú confirmas cada una."
|
||||
},
|
||||
"pages_write": {
|
||||
"title": "Crear páginas",
|
||||
"description": "El modelo puede proponer una pequeña aplicación que se abre en un marco aislado. Tú la confirmas."
|
||||
},
|
||||
"dashboard_write": {
|
||||
"title": "Cambiar el panel",
|
||||
"description": "El modelo puede proponer un nuevo diseño de tu panel de Inicio. Tú confirmas cada cambio."
|
||||
},
|
||||
"triggers_propose": {
|
||||
"title": "Proponer también desde aplicaciones de mensajería",
|
||||
"description": "El modelo puede proponer un disparador cuando alguien lo pide en una aplicación de mensajería. Tú lo confirmas."
|
||||
},
|
||||
"triggers_run": {
|
||||
"title": "Dejar que los disparadores empiecen desde aplicaciones de mensajería",
|
||||
"description": "Un disparador ligado a una conexión de mensajería puede iniciar una ejecución y entregar allí su resultado."
|
||||
},
|
||||
"talkback_channels": {
|
||||
"title": "Responder en canales conocidos",
|
||||
"description": "El modelo puede enviar un mensaje a un canal en el que ya habla."
|
||||
},
|
||||
"talkback_new_channel": {
|
||||
"title": "Iniciar canales nuevos",
|
||||
"description": "El modelo puede iniciar una conversación en un canal que no ha usado antes."
|
||||
},
|
||||
"files_upload": {
|
||||
"title": "Recibir archivos de aplicaciones de mensajería",
|
||||
"description": "Quien escribe puede adjuntar archivos para que el modelo los lea. No puede enviar archivos."
|
||||
},
|
||||
"act_files": {
|
||||
"title": "Escribir archivos por su cuenta",
|
||||
"description": "Una ejecución que nadie mira puede escribir archivos en las carpetas del agente."
|
||||
},
|
||||
"act_addons": {
|
||||
"title": "Usar acciones de complementos por su cuenta",
|
||||
"description": "Una ejecución que nadie mira puede llamar a las acciones de los complementos del agente."
|
||||
},
|
||||
"act_send": {
|
||||
"title": "Enviar mensajes por su cuenta",
|
||||
"description": "Una ejecución que nadie mira puede enviar mensajes más allá de su destino de entrega."
|
||||
},
|
||||
"act_spend": {
|
||||
"title": "Usar herramientas de pago o externas por su cuenta",
|
||||
"description": "Una ejecución que nadie mira puede usar herramientas de pago o externas y la red."
|
||||
}
|
||||
}
|
||||
},
|
||||
"vision": {
|
||||
|
||||
@@ -81,8 +81,7 @@
|
||||
"MCP": "MCP servers",
|
||||
"export": "Export",
|
||||
"Files": "Fichiers",
|
||||
"Tools": "Outils",
|
||||
"Grants": "Permissions"
|
||||
"Tools": "Outils"
|
||||
},
|
||||
"name": "Name",
|
||||
"description": "Description",
|
||||
@@ -137,17 +136,19 @@
|
||||
"all": "Tous les sites publics"
|
||||
},
|
||||
"toolsSummary": "{{on}} sur {{total}} activés",
|
||||
"toolsHelp": "Choisissez ce qu'un chat avec cet agent peut utiliser. Ce sont les mêmes interrupteurs que le menu Outils d'un chat. Un outil désactivé n'est jamais proposé au modèle, et un chat avec cet agent ne peut pas l'activer.",
|
||||
"toolsHelp": "Choisissez ce qu'une discussion avec cet agent peut utiliser. Ce sont les mêmes interrupteurs que le menu Outils d'une discussion, avec les options de chacun en dessous. Un outil désactivé n'est jamais proposé au modèle. Sans option cochée, l'agent garde les valeurs par défaut de ses connexions de messagerie ; dès que vous en cochez une, seules les cochées fonctionnent.",
|
||||
"toolsHeading": "Outils de cet agent",
|
||||
"skillsLater": "Un chat avec cet agent ne lit que les skills activées.",
|
||||
"skillsHeading": "Skills de cet agent",
|
||||
"grantsHelp": "What the agent may do beyond its tools. With no permission ticked, the agent keeps the defaults it had before permissions existed. Once you tick any, only the ticked ones work.",
|
||||
"grantsDefault": "Defaults",
|
||||
"countGrants": "{{count}} granted",
|
||||
"grantSensitive": "needs care",
|
||||
"grantsNoticeTitle": "Some messaging features will turn off.",
|
||||
"grantsNotice": "This agent had no permission list, so it kept these on its messaging connections: {{grants}}. They stop working until you tick them here.",
|
||||
"grantsAddMissing": "Add the missing permissions"
|
||||
"grantsAddMissing": "Add the missing permissions",
|
||||
"grantNames": {
|
||||
"triggers_propose": "Proposer aussi depuis les applications de messagerie",
|
||||
"triggers_run": "Laisser les déclencheurs démarrer depuis les applications de messagerie",
|
||||
"talkback_channels": "Répondre sur les canaux connus",
|
||||
"files_upload": "Recevoir des fichiers des applications de messagerie"
|
||||
}
|
||||
},
|
||||
"run": {
|
||||
"workingLine": "Working"
|
||||
|
||||
@@ -136,7 +136,8 @@
|
||||
"failed": "Enregistrement impossible. L'interrupteur revient à son état précédent.",
|
||||
"unavailable": "Indisponible dans ce chat",
|
||||
"toolCount_one": "{{count}} outil",
|
||||
"toolCount_other": "{{count}} outils"
|
||||
"toolCount_other": "{{count}} outils",
|
||||
"optionsOf": "Options de {{name}}"
|
||||
},
|
||||
"skills": {
|
||||
"label": "Compétences",
|
||||
|
||||
@@ -314,7 +314,7 @@
|
||||
"builtin": {
|
||||
"web": "Web",
|
||||
"saved_agents": "Agents enregistrés",
|
||||
"triggers": "Déclencheurs",
|
||||
"triggers": "Créer et gérer des déclencheurs",
|
||||
"shell": "Exécuter des commandes",
|
||||
"files": "Vos fichiers",
|
||||
"media": "Images et audio",
|
||||
@@ -334,15 +334,15 @@
|
||||
"isolated": "Les commandes s’exécutent isolées"
|
||||
},
|
||||
"describe": {
|
||||
"shell": "Le modèle peut exécuter des commandes shell et des scripts. Ils tournent dans un add-on qui les isole s'il y en a un d'installé, sinon directement sur cette machine.",
|
||||
"files": "Le modèle peut lister, lire, écrire, modifier, déplacer, supprimer et chercher vos fichiers, et lire des documents. Un chat d'un agent qui travaille dans un seul dossier n'atteint que ce dossier.",
|
||||
"web": "Le modèle peut chercher sur le web et lire une page publique à partir de son adresse. Les adresses de votre réseau sont refusées, sauf si un administrateur les autorise.",
|
||||
"media": "Le modèle peut décrire une image ou transcrire un enregistrement de vos fichiers avec un modèle auxiliaire.",
|
||||
"collections": "Le modèle peut lister vos collections et y chercher les passages qui répondent à une question.",
|
||||
"subagents": "Le modèle peut lancer un sous-agent qui travaille sur une tâche avec les mêmes interrupteurs que ce chat, puis fait son rapport.",
|
||||
"saved_agents": "Le modèle peut lister vos agents enregistrés et en lancer un comme sous-agent, avec les instructions et le modèle de cet agent.",
|
||||
"triggers": "Le modèle peut proposer, lister, modifier et supprimer des déclencheurs : des tâches qui s'exécutent d'elles-mêmes à une heure fixée ou quand un fichier arrive dans un dossier. Un nouveau déclencheur ou une modification attend sur une carte du chat jusqu'à votre confirmation ; mettre en pause ou reprendre s'applique tout de suite et vous pouvez l'annuler.",
|
||||
"changes": "Le modèle peut proposer une modification de vos notes de mémoire ou des règles permanentes d'un agent, et annuler une modification que vous avez confirmée. Rien ne change tant que vous ne confirmez pas la proposition sur une carte du chat."
|
||||
"shell": "Le modèle peut exécuter des commandes shell et des scripts.",
|
||||
"files": "Le modèle peut lister, lire, écrire et chercher dans vos fichiers.",
|
||||
"web": "Le modèle peut chercher sur le web et lire des pages publiques.",
|
||||
"media": "Le modèle peut décrire des images et transcrire des enregistrements de vos fichiers.",
|
||||
"collections": "Le modèle peut chercher dans vos collections.",
|
||||
"subagents": "Le modèle peut lancer un sous-agent pour une tâche et recevoir son rapport.",
|
||||
"saved_agents": "Le modèle peut lancer l'un de vos agents enregistrés comme sous-agent.",
|
||||
"triggers": "Le modèle peut proposer, lister, modifier et supprimer des déclencheurs. Vous confirmez chaque nouveau déclencheur ou changement.",
|
||||
"changes": "Le modèle peut proposer des changements à votre mémoire et aux fichiers d'un agent. Vous confirmez chacun."
|
||||
},
|
||||
"whenOff": {
|
||||
"shell": "Le modèle peut écrire des fichiers mais ne peut rien exécuter.",
|
||||
@@ -352,7 +352,7 @@
|
||||
"collections": "Le modèle ne peut pas lire vos collections.",
|
||||
"subagents": "Le modèle travaille seul.",
|
||||
"saved_agents": "Le modèle ne peut ni voir ni lancer vos agents enregistrés.",
|
||||
"triggers": "Le modèle ne peut ni créer ni gérer de déclencheurs. Une exécution lancée par un déclencheur ou un connecteur n'en a jamais.",
|
||||
"triggers": "Le modèle ne peut ni proposer ni gérer de déclencheurs.",
|
||||
"changes": "Le modèle ne peut pas proposer de modifications de votre mémoire ou des règles d'un agent."
|
||||
},
|
||||
"addonDescribe_one": "Donne au modèle {{count}} outil de cet add-on.",
|
||||
@@ -360,7 +360,7 @@
|
||||
"serverDescribe": "Un serveur MCP du modèle : ses outils sont proposés au modèle.",
|
||||
"connectorDescribe": "L'un de vos connecteurs MCP : ses outils sont proposés au modèle.",
|
||||
"gone": "Plus disponible ici. Désactivez-le pour le retirer.",
|
||||
"grants": "Ce que l'agent peut modifier",
|
||||
"grants": "Autres autorisations",
|
||||
"grantSensitive": "Sensible : cela change ce que l'agent pourra faire ou atteindre plus tard.",
|
||||
"connection": {
|
||||
"label": "Connexions",
|
||||
@@ -374,6 +374,77 @@
|
||||
"agentLabel": "Connexions pour les chats de cet agent",
|
||||
"agentHelp": "Les chats de cet agent ne peuvent utiliser que ces connexions et ne peuvent pas les changer.",
|
||||
"perChatHelp": "Aucune choisie : chaque chat choisit les siennes."
|
||||
},
|
||||
"optionNeeds": "Activez « {{name}} » pour l'utiliser.",
|
||||
"connectionMissing": "{{name}} ne l'autorise pas encore.",
|
||||
"connectionOpen": "Ouvrir ses autorisations",
|
||||
"section": {
|
||||
"messaging": {
|
||||
"title": "Applications de messagerie",
|
||||
"intro": "Cela concerne les discussions qui démarrent dans une application de messagerie. La connexion doit autoriser la même chose sur sa propre page d'autorisations."
|
||||
},
|
||||
"unattended": {
|
||||
"title": "Quand personne ne regarde",
|
||||
"intro": "Cela concerne les exécutions lancées par un déclencheur ou une application de messagerie, où personne ne peut confirmer une étape."
|
||||
}
|
||||
},
|
||||
"grant": {
|
||||
"memory_write": {
|
||||
"title": "Retenir des choses",
|
||||
"description": "Le modèle peut proposer une note pour votre mémoire ou celle de l'agent. Vous confirmez chaque note."
|
||||
},
|
||||
"profile_write": {
|
||||
"title": "Changer ses propres règles",
|
||||
"description": "Le modèle peut proposer une modification des règles permanentes de l'agent. Vous confirmez chaque modification."
|
||||
},
|
||||
"skills_write": {
|
||||
"title": "Écrire des skills",
|
||||
"description": "Le modèle peut proposer un skill nouveau ou modifié. Vous confirmez chacun."
|
||||
},
|
||||
"pages_write": {
|
||||
"title": "Créer des pages",
|
||||
"description": "Le modèle peut proposer une petite application qui s'ouvre dans un cadre isolé. Vous la confirmez."
|
||||
},
|
||||
"dashboard_write": {
|
||||
"title": "Changer le tableau de bord",
|
||||
"description": "Le modèle peut proposer une nouvelle disposition de votre tableau de bord d'accueil. Vous confirmez chaque changement."
|
||||
},
|
||||
"triggers_propose": {
|
||||
"title": "Proposer aussi depuis les applications de messagerie",
|
||||
"description": "Le modèle peut proposer un déclencheur quand quelqu'un le demande dans une application de messagerie. Vous le confirmez."
|
||||
},
|
||||
"triggers_run": {
|
||||
"title": "Laisser les déclencheurs démarrer depuis les applications de messagerie",
|
||||
"description": "Un déclencheur lié à une connexion de messagerie peut lancer une exécution et y livrer son résultat."
|
||||
},
|
||||
"talkback_channels": {
|
||||
"title": "Répondre sur les canaux connus",
|
||||
"description": "Le modèle peut envoyer un message à un canal où il intervient déjà."
|
||||
},
|
||||
"talkback_new_channel": {
|
||||
"title": "Ouvrir de nouveaux canaux",
|
||||
"description": "Le modèle peut démarrer une conversation sur un canal qu'il n'a jamais utilisé."
|
||||
},
|
||||
"files_upload": {
|
||||
"title": "Recevoir des fichiers des applications de messagerie",
|
||||
"description": "Les expéditeurs peuvent joindre des fichiers que le modèle lit. Il ne peut pas en envoyer."
|
||||
},
|
||||
"act_files": {
|
||||
"title": "Écrire des fichiers de lui-même",
|
||||
"description": "Une exécution que personne ne surveille peut écrire des fichiers dans les dossiers de l'agent."
|
||||
},
|
||||
"act_addons": {
|
||||
"title": "Utiliser seul les actions des add-ons",
|
||||
"description": "Une exécution que personne ne surveille peut appeler les actions des add-ons de l'agent."
|
||||
},
|
||||
"act_send": {
|
||||
"title": "Envoyer seul des messages",
|
||||
"description": "Une exécution que personne ne surveille peut envoyer des messages au-delà de sa cible de livraison."
|
||||
},
|
||||
"act_spend": {
|
||||
"title": "Utiliser seul des outils payants ou externes",
|
||||
"description": "Une exécution que personne ne surveille peut utiliser des outils payants ou externes et le réseau."
|
||||
}
|
||||
}
|
||||
},
|
||||
"vision": {
|
||||
|
||||
@@ -81,8 +81,7 @@
|
||||
"MCP": "MCP servers",
|
||||
"export": "Export",
|
||||
"Files": "File",
|
||||
"Tools": "Alat",
|
||||
"Grants": "Permissions"
|
||||
"Tools": "Alat"
|
||||
},
|
||||
"name": "Name",
|
||||
"description": "Description",
|
||||
@@ -137,17 +136,19 @@
|
||||
"all": "Semua situs publik"
|
||||
},
|
||||
"toolsSummary": "{{on}} dari {{total}} aktif",
|
||||
"toolsHelp": "Pilih apa yang dapat dipakai chat dengan agen ini. Sakelarnya sama dengan menu Alat pada chat. Alat yang mati tidak pernah ditawarkan kepada model, dan chat dengan agen ini tidak dapat menyalakannya.",
|
||||
"toolsHelp": "Pilih apa yang dapat dipakai obrolan dengan agen ini. Ini sakelar yang sama dengan menu Alat pada obrolan, dengan opsi tiap sakelar di bawahnya. Alat yang mati tidak pernah ditawarkan ke model. Tanpa opsi yang dicentang, agen memakai bawaan koneksi pesannya; setelah Anda mencentang satu, hanya yang dicentang yang berlaku.",
|
||||
"toolsHeading": "Alat agen ini",
|
||||
"skillsLater": "Chat dengan agen ini hanya membaca skill yang aktif.",
|
||||
"skillsHeading": "Skill agen ini",
|
||||
"grantsHelp": "What the agent may do beyond its tools. With no permission ticked, the agent keeps the defaults it had before permissions existed. Once you tick any, only the ticked ones work.",
|
||||
"grantsDefault": "Defaults",
|
||||
"countGrants": "{{count}} granted",
|
||||
"grantSensitive": "needs care",
|
||||
"grantsNoticeTitle": "Some messaging features will turn off.",
|
||||
"grantsNotice": "This agent had no permission list, so it kept these on its messaging connections: {{grants}}. They stop working until you tick them here.",
|
||||
"grantsAddMissing": "Add the missing permissions"
|
||||
"grantsAddMissing": "Add the missing permissions",
|
||||
"grantNames": {
|
||||
"triggers_propose": "Usulkan juga dari aplikasi pesan",
|
||||
"triggers_run": "Biarkan pemicu dimulai dari aplikasi pesan",
|
||||
"talkback_channels": "Membalas di kanal yang dikenal",
|
||||
"files_upload": "Menerima file dari aplikasi pesan"
|
||||
}
|
||||
},
|
||||
"run": {
|
||||
"workingLine": "Working"
|
||||
|
||||
@@ -188,7 +188,8 @@
|
||||
"failed": "Gagal menyimpan. Sakelar kembali seperti semula.",
|
||||
"unavailable": "Tidak tersedia di obrolan ini",
|
||||
"toolCount_one": "{{count}} alat",
|
||||
"toolCount_other": "{{count}} alat"
|
||||
"toolCount_other": "{{count}} alat",
|
||||
"optionsOf": "Opsi {{name}}"
|
||||
},
|
||||
"skills": {
|
||||
"label": "Keahlian",
|
||||
|
||||
@@ -314,7 +314,7 @@
|
||||
"builtin": {
|
||||
"web": "Web",
|
||||
"saved_agents": "Agen tersimpan",
|
||||
"triggers": "Pemicu",
|
||||
"triggers": "Buat dan kelola pemicu",
|
||||
"shell": "Jalankan perintah",
|
||||
"files": "File Anda",
|
||||
"media": "Gambar dan audio",
|
||||
@@ -334,15 +334,15 @@
|
||||
"isolated": "Perintah berjalan terisolasi"
|
||||
},
|
||||
"describe": {
|
||||
"shell": "Model dapat menjalankan perintah shell dan skrip. Perintah berjalan di add-on yang mengisolasinya jika ada yang terpasang, jika tidak langsung di mesin ini.",
|
||||
"files": "Model dapat membuat daftar, membaca, menulis, mengedit, memindahkan, menghapus, dan mencari berkas Anda, serta membaca dokumen. Chat agen yang bekerja di satu folder hanya menjangkau folder itu.",
|
||||
"web": "Model dapat mencari di web dan membaca halaman publik dari alamatnya. Alamat di dalam jaringan Anda ditolak kecuali administrator mengizinkannya.",
|
||||
"media": "Model dapat mendeskripsikan gambar atau menyalin rekaman dari berkas Anda menjadi teks dengan model pembantu.",
|
||||
"collections": "Model dapat membuat daftar koleksi Anda dan mencari bagian yang cocok dengan sebuah pertanyaan.",
|
||||
"subagents": "Model dapat memulai sub-agen yang mengerjakan satu tugas dengan sakelar yang sama seperti chat ini, lalu melapor.",
|
||||
"saved_agents": "Model dapat membuat daftar agen tersimpan Anda dan memulai salah satunya sebagai sub-agen, dengan instruksi dan model agen itu.",
|
||||
"triggers": "Model dapat mengusulkan, membuat daftar, mengubah, dan menghapus pemicu: tugas yang berjalan sendiri pada waktu tertentu atau saat berkas masuk ke folder. Pemicu baru atau perubahan menunggu di kartu dalam chat sampai Anda mengonfirmasi; menjeda atau melanjutkan pemicu berlaku langsung dan bisa dibatalkan.",
|
||||
"changes": "Model dapat mengusulkan perubahan pada catatan memori Anda atau aturan tetap sebuah agen, dan membatalkan perubahan yang sudah Anda konfirmasi. Tidak ada yang berubah sampai Anda mengonfirmasi usulan di kartu dalam chat."
|
||||
"shell": "Model dapat menjalankan perintah shell dan skrip.",
|
||||
"files": "Model dapat mencantumkan, membaca, menulis, dan mencari file Anda.",
|
||||
"web": "Model dapat mencari di web dan membaca halaman publik.",
|
||||
"media": "Model dapat mendeskripsikan gambar dan mentranskripsi rekaman dari file Anda.",
|
||||
"collections": "Model dapat mencari di koleksi Anda.",
|
||||
"subagents": "Model dapat memulai sub-agen untuk satu tugas dan menerima laporannya.",
|
||||
"saved_agents": "Model dapat memulai salah satu agen tersimpan Anda sebagai sub-agen.",
|
||||
"triggers": "Model dapat mengusulkan, mencantumkan, mengubah, dan menghapus pemicu. Anda mengonfirmasi setiap pemicu atau perubahan baru.",
|
||||
"changes": "Model dapat mengusulkan perubahan pada memori Anda dan file agen. Anda mengonfirmasi setiap perubahan."
|
||||
},
|
||||
"whenOff": {
|
||||
"shell": "Model dapat menulis berkas tetapi tidak dapat menjalankan apa pun.",
|
||||
@@ -352,7 +352,7 @@
|
||||
"collections": "Model tidak dapat membaca koleksi Anda.",
|
||||
"subagents": "Model bekerja sendiri.",
|
||||
"saved_agents": "Model tidak dapat melihat atau memulai agen tersimpan Anda.",
|
||||
"triggers": "Model tidak dapat membuat atau mengelola pemicu. Proses yang dimulai oleh pemicu atau konektor tidak pernah memilikinya.",
|
||||
"triggers": "Model tidak dapat mengusulkan atau mengelola pemicu.",
|
||||
"changes": "Model tidak dapat mengusulkan perubahan pada memori Anda atau aturan agen."
|
||||
},
|
||||
"addonDescribe_one": "Memberi model {{count}} alat dari add-on ini.",
|
||||
@@ -360,7 +360,7 @@
|
||||
"serverDescribe": "Server MCP milik model: alatnya ditawarkan kepada model.",
|
||||
"connectorDescribe": "Salah satu konektor MCP Anda: alatnya ditawarkan kepada model.",
|
||||
"gone": "Tidak tersedia lagi di sini. Matikan untuk menghapusnya.",
|
||||
"grants": "Yang boleh diubah agen",
|
||||
"grants": "Izin lainnya",
|
||||
"grantSensitive": "Sensitif: ini mengubah apa yang boleh dilakukan atau dijangkau agen nanti.",
|
||||
"connection": {
|
||||
"label": "Koneksi",
|
||||
@@ -374,6 +374,77 @@
|
||||
"agentLabel": "Koneksi untuk chat agen ini",
|
||||
"agentHelp": "Chat agen ini hanya boleh memakai koneksi ini dan tidak bisa mengubahnya.",
|
||||
"perChatHelp": "Belum dipilih: setiap chat memilih sendiri."
|
||||
},
|
||||
"optionNeeds": "Aktifkan “{{name}}” untuk menggunakannya.",
|
||||
"connectionMissing": "{{name}} belum mengizinkan ini.",
|
||||
"connectionOpen": "Buka izinnya",
|
||||
"section": {
|
||||
"messaging": {
|
||||
"title": "Aplikasi pesan",
|
||||
"intro": "Berlaku untuk obrolan yang dimulai di aplikasi pesan. Koneksi harus mengizinkan hal yang sama di halaman izinnya sendiri."
|
||||
},
|
||||
"unattended": {
|
||||
"title": "Saat tidak ada yang mengawasi",
|
||||
"intro": "Berlaku untuk proses yang dimulai oleh pemicu atau aplikasi pesan, tempat tidak ada yang bisa mengonfirmasi satu langkah."
|
||||
}
|
||||
},
|
||||
"grant": {
|
||||
"memory_write": {
|
||||
"title": "Mengingat hal",
|
||||
"description": "Model dapat mengusulkan catatan untuk memori Anda atau memori agen. Anda mengonfirmasi setiap catatan."
|
||||
},
|
||||
"profile_write": {
|
||||
"title": "Mengubah aturannya sendiri",
|
||||
"description": "Model dapat mengusulkan perubahan pada aturan tetap agen. Anda mengonfirmasi setiap perubahan."
|
||||
},
|
||||
"skills_write": {
|
||||
"title": "Menulis skill",
|
||||
"description": "Model dapat mengusulkan skill baru atau yang diubah. Anda mengonfirmasi masing-masing."
|
||||
},
|
||||
"pages_write": {
|
||||
"title": "Membuat halaman",
|
||||
"description": "Model dapat mengusulkan aplikasi kecil yang terbuka dalam bingkai terisolasi. Anda mengonfirmasinya."
|
||||
},
|
||||
"dashboard_write": {
|
||||
"title": "Mengubah dasbor",
|
||||
"description": "Model dapat mengusulkan tata letak baru untuk dasbor Beranda Anda. Anda mengonfirmasi setiap perubahan."
|
||||
},
|
||||
"triggers_propose": {
|
||||
"title": "Usulkan juga dari aplikasi pesan",
|
||||
"description": "Model dapat mengusulkan pemicu saat seseorang memintanya di aplikasi pesan. Anda mengonfirmasinya."
|
||||
},
|
||||
"triggers_run": {
|
||||
"title": "Biarkan pemicu dimulai dari aplikasi pesan",
|
||||
"description": "Pemicu yang terikat pada koneksi pesan dapat memulai proses dan mengirim hasilnya ke sana."
|
||||
},
|
||||
"talkback_channels": {
|
||||
"title": "Membalas di kanal yang dikenal",
|
||||
"description": "Model dapat mengirim pesan ke kanal yang sudah dipakainya."
|
||||
},
|
||||
"talkback_new_channel": {
|
||||
"title": "Memulai kanal baru",
|
||||
"description": "Model dapat memulai percakapan di kanal yang belum pernah dipakainya."
|
||||
},
|
||||
"files_upload": {
|
||||
"title": "Menerima file dari aplikasi pesan",
|
||||
"description": "Pengirim dapat melampirkan file untuk dibaca model. Model tidak dapat mengirim file keluar."
|
||||
},
|
||||
"act_files": {
|
||||
"title": "Menulis file sendiri",
|
||||
"description": "Proses yang tidak diawasi dapat menulis file di folder agen."
|
||||
},
|
||||
"act_addons": {
|
||||
"title": "Memakai aksi add-on sendiri",
|
||||
"description": "Proses yang tidak diawasi dapat memanggil aksi add-on milik agen."
|
||||
},
|
||||
"act_send": {
|
||||
"title": "Mengirim pesan sendiri",
|
||||
"description": "Proses yang tidak diawasi dapat mengirim pesan di luar tujuan pengirimannya."
|
||||
},
|
||||
"act_spend": {
|
||||
"title": "Memakai alat berbayar atau eksternal sendiri",
|
||||
"description": "Proses yang tidak diawasi dapat memakai alat berbayar atau eksternal dan jaringan."
|
||||
}
|
||||
}
|
||||
},
|
||||
"vision": {
|
||||
|
||||
@@ -81,8 +81,7 @@
|
||||
"MCP": "MCP servers",
|
||||
"export": "Export",
|
||||
"Files": "File",
|
||||
"Tools": "Strumenti",
|
||||
"Grants": "Permissions"
|
||||
"Tools": "Strumenti"
|
||||
},
|
||||
"name": "Name",
|
||||
"description": "Description",
|
||||
@@ -137,17 +136,19 @@
|
||||
"all": "Tutti i siti pubblici"
|
||||
},
|
||||
"toolsSummary": "{{on}} su {{total}} attivi",
|
||||
"toolsHelp": "Scegli cosa può usare una chat con questo agente. Sono gli stessi interruttori del menu Strumenti di una chat. Uno strumento spento non viene mai offerto al modello, e una chat con questo agente non può accenderlo.",
|
||||
"toolsHelp": "Scegli cosa può usare una chat con questo agente. Sono gli stessi interruttori del menu Strumenti di una chat, con le opzioni di ciascuno sotto. Uno strumento disattivato non viene mai offerto al modello. Senza opzioni spuntate, l'agente mantiene i valori predefiniti delle sue connessioni di messaggistica; appena ne spunti una, funzionano solo quelle spuntate.",
|
||||
"toolsHeading": "Strumenti di questo agente",
|
||||
"skillsLater": "Una chat con questo agente legge solo le skill attive.",
|
||||
"skillsHeading": "Skill di questo agente",
|
||||
"grantsHelp": "What the agent may do beyond its tools. With no permission ticked, the agent keeps the defaults it had before permissions existed. Once you tick any, only the ticked ones work.",
|
||||
"grantsDefault": "Defaults",
|
||||
"countGrants": "{{count}} granted",
|
||||
"grantSensitive": "needs care",
|
||||
"grantsNoticeTitle": "Some messaging features will turn off.",
|
||||
"grantsNotice": "This agent had no permission list, so it kept these on its messaging connections: {{grants}}. They stop working until you tick them here.",
|
||||
"grantsAddMissing": "Add the missing permissions"
|
||||
"grantsAddMissing": "Add the missing permissions",
|
||||
"grantNames": {
|
||||
"triggers_propose": "Proponi anche dalle app di messaggistica",
|
||||
"triggers_run": "Lascia partire i trigger dalle app di messaggistica",
|
||||
"talkback_channels": "Rispondere sui canali noti",
|
||||
"files_upload": "Ricevere file dalle app di messaggistica"
|
||||
}
|
||||
},
|
||||
"run": {
|
||||
"workingLine": "Working"
|
||||
|
||||
@@ -138,7 +138,8 @@
|
||||
"failed": "Salvataggio non riuscito. L'interruttore è tornato com'era.",
|
||||
"unavailable": "Non disponibile in questa chat",
|
||||
"toolCount_one": "{{count}} strumento",
|
||||
"toolCount_other": "{{count}} strumenti"
|
||||
"toolCount_other": "{{count}} strumenti",
|
||||
"optionsOf": "Opzioni di {{name}}"
|
||||
},
|
||||
"skills": {
|
||||
"label": "Skill",
|
||||
|
||||
@@ -314,7 +314,7 @@
|
||||
"builtin": {
|
||||
"web": "Web",
|
||||
"saved_agents": "Agenti salvati",
|
||||
"triggers": "Trigger",
|
||||
"triggers": "Crea e gestisci i trigger",
|
||||
"shell": "Esegui comandi",
|
||||
"files": "I tuoi file",
|
||||
"media": "Immagini e audio",
|
||||
@@ -334,15 +334,15 @@
|
||||
"isolated": "I comandi girano isolati"
|
||||
},
|
||||
"describe": {
|
||||
"shell": "Il modello può eseguire comandi di shell e script. Girano in un add-on che li isola, se ce n'è uno installato, altrimenti direttamente su questa macchina.",
|
||||
"files": "Il modello può elencare, leggere, scrivere, modificare, spostare, eliminare e cercare i tuoi file, e leggere documenti. Una chat di un agente che lavora in una sola cartella raggiunge solo quella cartella.",
|
||||
"web": "Il modello può cercare sul web e leggere una pagina pubblica dal suo indirizzo. Gli indirizzi dentro la tua rete sono rifiutati, a meno che un amministratore li permetta.",
|
||||
"media": "Il modello può descrivere un'immagine o trascrivere una registrazione dai tuoi file con un modello di supporto.",
|
||||
"collections": "Il modello può elencare le tue raccolte e cercarvi i passaggi che rispondono a una domanda.",
|
||||
"subagents": "Il modello può avviare un sotto-agente che lavora su un compito con gli stessi interruttori di questa chat e poi riferisce.",
|
||||
"saved_agents": "Il modello può elencare i tuoi agenti salvati e avviarne uno come sotto-agente, con le istruzioni e il modello di quell'agente.",
|
||||
"triggers": "Il modello può proporre, elencare, modificare ed eliminare trigger: attività che partono da sole a un'ora stabilita o quando arriva un file in una cartella. Un nuovo trigger o una modifica aspetta su una scheda nella chat finché non la confermi; mettere in pausa o riprendere un trigger vale subito e puoi annullarlo.",
|
||||
"changes": "Il modello può proporre una modifica alle tue note di memoria o alle regole fisse di un agente, e annullare una modifica che hai confermato. Nulla cambia finché non confermi la proposta su una scheda nella chat."
|
||||
"shell": "Il modello può eseguire comandi shell e script.",
|
||||
"files": "Il modello può elencare, leggere, scrivere e cercare nei tuoi file.",
|
||||
"web": "Il modello può cercare sul web e leggere pagine pubbliche.",
|
||||
"media": "Il modello può descrivere immagini e trascrivere registrazioni dai tuoi file.",
|
||||
"collections": "Il modello può cercare nelle tue raccolte.",
|
||||
"subagents": "Il modello può avviare un sotto-agente per un compito e ricevere il suo rapporto.",
|
||||
"saved_agents": "Il modello può avviare uno dei tuoi agenti salvati come sotto-agente.",
|
||||
"triggers": "Il modello può proporre, elencare, modificare ed eliminare trigger. Confermi tu ogni nuovo trigger o modifica.",
|
||||
"changes": "Il modello può proporre modifiche alla tua memoria e ai file di un agente. Confermi tu ognuna."
|
||||
},
|
||||
"whenOff": {
|
||||
"shell": "Il modello può scrivere file ma non può eseguire nulla.",
|
||||
@@ -352,7 +352,7 @@
|
||||
"collections": "Il modello non può leggere le tue raccolte.",
|
||||
"subagents": "Il modello lavora da solo.",
|
||||
"saved_agents": "Il modello non può vedere né avviare i tuoi agenti salvati.",
|
||||
"triggers": "Il modello non può creare né gestire trigger. Una esecuzione avviata da un trigger o da un connettore non li ha mai.",
|
||||
"triggers": "Il modello non può proporre né gestire trigger.",
|
||||
"changes": "Il modello non può proporre modifiche alla tua memoria o alle regole di un agente."
|
||||
},
|
||||
"addonDescribe_one": "Dà al modello {{count}} strumento di questo add-on.",
|
||||
@@ -360,7 +360,7 @@
|
||||
"serverDescribe": "Un server MCP del modello: i suoi strumenti sono offerti al modello.",
|
||||
"connectorDescribe": "Uno dei tuoi connettori MCP: i suoi strumenti sono offerti al modello.",
|
||||
"gone": "Non più disponibile qui. Spegnilo per rimuoverlo.",
|
||||
"grants": "Cosa può modificare l'agente",
|
||||
"grants": "Altri permessi",
|
||||
"grantSensitive": "Sensibile: cambia ciò che l'agente potrà fare o raggiungere in seguito.",
|
||||
"connection": {
|
||||
"label": "Connessioni",
|
||||
@@ -374,6 +374,77 @@
|
||||
"agentLabel": "Connessioni per le chat di questo agente",
|
||||
"agentHelp": "Le chat di questo agente possono usare solo queste connessioni e non possono cambiarle.",
|
||||
"perChatHelp": "Nessuna scelta: ogni chat sceglie la sua."
|
||||
},
|
||||
"optionNeeds": "Attiva «{{name}}» per usarlo.",
|
||||
"connectionMissing": "{{name}} non lo consente ancora.",
|
||||
"connectionOpen": "Apri i suoi permessi",
|
||||
"section": {
|
||||
"messaging": {
|
||||
"title": "App di messaggistica",
|
||||
"intro": "Vale per le chat che iniziano in un'app di messaggistica. La connessione deve consentire la stessa cosa nella sua pagina dei permessi."
|
||||
},
|
||||
"unattended": {
|
||||
"title": "Quando nessuno guarda",
|
||||
"intro": "Vale per le esecuzioni avviate da un trigger o da un'app di messaggistica, dove nessuno può confermare un passaggio."
|
||||
}
|
||||
},
|
||||
"grant": {
|
||||
"memory_write": {
|
||||
"title": "Ricordare le cose",
|
||||
"description": "Il modello può proporre una nota per la tua memoria o per quella dell'agente. Confermi tu ogni nota."
|
||||
},
|
||||
"profile_write": {
|
||||
"title": "Cambiare le proprie regole",
|
||||
"description": "Il modello può proporre una modifica alle regole permanenti dell'agente. Confermi tu ogni modifica."
|
||||
},
|
||||
"skills_write": {
|
||||
"title": "Scrivere skill",
|
||||
"description": "Il modello può proporre una skill nuova o modificata. Confermi tu ognuna."
|
||||
},
|
||||
"pages_write": {
|
||||
"title": "Creare pagine",
|
||||
"description": "Il modello può proporre una piccola app che si apre in un frame isolato. La confermi tu."
|
||||
},
|
||||
"dashboard_write": {
|
||||
"title": "Cambiare la dashboard",
|
||||
"description": "Il modello può proporre un nuovo layout della tua dashboard Home. Confermi tu ogni modifica."
|
||||
},
|
||||
"triggers_propose": {
|
||||
"title": "Proponi anche dalle app di messaggistica",
|
||||
"description": "Il modello può proporre un trigger quando qualcuno lo chiede in un'app di messaggistica. Lo confermi tu."
|
||||
},
|
||||
"triggers_run": {
|
||||
"title": "Lascia partire i trigger dalle app di messaggistica",
|
||||
"description": "Un trigger legato a una connessione di messaggistica può avviare un'esecuzione e consegnare lì il risultato."
|
||||
},
|
||||
"talkback_channels": {
|
||||
"title": "Rispondere sui canali noti",
|
||||
"description": "Il modello può inviare un messaggio a un canale in cui già interviene."
|
||||
},
|
||||
"talkback_new_channel": {
|
||||
"title": "Aprire nuovi canali",
|
||||
"description": "Il modello può iniziare una conversazione su un canale che non ha mai usato."
|
||||
},
|
||||
"files_upload": {
|
||||
"title": "Ricevere file dalle app di messaggistica",
|
||||
"description": "Chi scrive può allegare file che il modello legge. Non può inviare file."
|
||||
},
|
||||
"act_files": {
|
||||
"title": "Scrivere file da solo",
|
||||
"description": "Un'esecuzione che nessuno guarda può scrivere file nelle cartelle dell'agente."
|
||||
},
|
||||
"act_addons": {
|
||||
"title": "Usare da solo le azioni dei componenti aggiuntivi",
|
||||
"description": "Un'esecuzione che nessuno guarda può chiamare le azioni dei componenti aggiuntivi dell'agente."
|
||||
},
|
||||
"act_send": {
|
||||
"title": "Inviare messaggi da solo",
|
||||
"description": "Un'esecuzione che nessuno guarda può inviare messaggi oltre la sua destinazione di consegna."
|
||||
},
|
||||
"act_spend": {
|
||||
"title": "Usare da solo strumenti a pagamento o esterni",
|
||||
"description": "Un'esecuzione che nessuno guarda può usare strumenti a pagamento o esterni e la rete."
|
||||
}
|
||||
}
|
||||
},
|
||||
"vision": {
|
||||
|
||||
@@ -81,8 +81,7 @@
|
||||
"MCP": "MCP servers",
|
||||
"export": "Export",
|
||||
"Files": "파일",
|
||||
"Tools": "도구",
|
||||
"Grants": "Permissions"
|
||||
"Tools": "도구"
|
||||
},
|
||||
"name": "Name",
|
||||
"description": "Description",
|
||||
@@ -137,17 +136,19 @@
|
||||
"all": "모든 공개 사이트"
|
||||
},
|
||||
"toolsSummary": "{{total}}개 중 {{on}}개 켜짐",
|
||||
"toolsHelp": "이 에이전트와의 채팅이 사용할 수 있는 것을 고르세요. 채팅의 도구 메뉴와 같은 스위치입니다. 꺼진 도구는 모델에 제공되지 않으며, 이 에이전트와의 채팅에서 켤 수 없습니다.",
|
||||
"toolsHelp": "이 에이전트와의 채팅이 쓸 수 있는 것을 고르세요. 채팅의 도구 메뉴와 같은 스위치이며, 각 스위치의 옵션이 그 아래에 있습니다. 꺼진 도구는 모델에 제공되지 않습니다. 체크한 옵션이 없으면 에이전트는 메신저 연결의 기본값을 유지하고, 하나라도 체크하면 체크한 것만 작동합니다.",
|
||||
"toolsHeading": "이 에이전트의 도구",
|
||||
"skillsLater": "이 에이전트와의 채팅은 켜진 스킬만 읽습니다.",
|
||||
"skillsHeading": "이 에이전트의 스킬",
|
||||
"grantsHelp": "What the agent may do beyond its tools. With no permission ticked, the agent keeps the defaults it had before permissions existed. Once you tick any, only the ticked ones work.",
|
||||
"grantsDefault": "Defaults",
|
||||
"countGrants": "{{count}} granted",
|
||||
"grantSensitive": "needs care",
|
||||
"grantsNoticeTitle": "Some messaging features will turn off.",
|
||||
"grantsNotice": "This agent had no permission list, so it kept these on its messaging connections: {{grants}}. They stop working until you tick them here.",
|
||||
"grantsAddMissing": "Add the missing permissions"
|
||||
"grantsAddMissing": "Add the missing permissions",
|
||||
"grantNames": {
|
||||
"triggers_propose": "메신저 앱에서도 제안",
|
||||
"triggers_run": "메신저 앱에서 트리거 시작 허용",
|
||||
"talkback_channels": "알려진 채널에 답장",
|
||||
"files_upload": "메신저 앱에서 파일 받기"
|
||||
}
|
||||
},
|
||||
"run": {
|
||||
"workingLine": "Working"
|
||||
|
||||
@@ -138,7 +138,8 @@
|
||||
"failed": "저장하지 못했습니다. 스위치가 이전 상태로 돌아갔습니다.",
|
||||
"unavailable": "이 채팅에서 사용할 수 없음",
|
||||
"toolCount_one": "도구 {{count}}개",
|
||||
"toolCount_other": "도구 {{count}}개"
|
||||
"toolCount_other": "도구 {{count}}개",
|
||||
"optionsOf": "{{name}} 옵션"
|
||||
},
|
||||
"skills": {
|
||||
"label": "스킬",
|
||||
|
||||
@@ -314,7 +314,7 @@
|
||||
"builtin": {
|
||||
"web": "웹",
|
||||
"saved_agents": "저장된 에이전트",
|
||||
"triggers": "트리거",
|
||||
"triggers": "트리거 만들기 및 관리",
|
||||
"shell": "명령 실행",
|
||||
"files": "내 파일",
|
||||
"media": "이미지와 오디오",
|
||||
@@ -334,15 +334,15 @@
|
||||
"isolated": "명령이 격리되어 실행됩니다"
|
||||
},
|
||||
"describe": {
|
||||
"shell": "모델이 셸 명령과 스크립트를 실행할 수 있습니다. 격리하는 애드온이 설치되어 있으면 그 안에서, 없으면 이 기기에서 바로 실행됩니다.",
|
||||
"files": "모델이 내 파일을 나열, 읽기, 쓰기, 편집, 이동, 삭제, 검색하고 문서를 읽을 수 있습니다. 한 폴더에서만 일하는 에이전트의 채팅은 그 폴더에만 접근합니다.",
|
||||
"web": "모델이 웹을 검색하고 주소로 공개 페이지를 읽을 수 있습니다. 내 네트워크 안의 주소는 관리자가 허용하지 않으면 거부됩니다.",
|
||||
"media": "모델이 보조 모델로 내 파일의 이미지를 설명하거나 녹음을 받아 적을 수 있습니다.",
|
||||
"collections": "모델이 내 컬렉션을 나열하고 질문에 맞는 구절을 검색할 수 있습니다.",
|
||||
"subagents": "모델이 이 채팅과 같은 스위치로 한 가지 작업을 하는 하위 에이전트를 시작하고 결과를 보고받을 수 있습니다.",
|
||||
"saved_agents": "모델이 저장된 에이전트를 나열하고, 그 에이전트의 지침과 모델로 하위 에이전트로 시작할 수 있습니다.",
|
||||
"triggers": "모델이 트리거를 제안, 나열, 변경, 삭제할 수 있습니다. 트리거는 정해진 시간이나 폴더에 파일이 도착할 때 스스로 실행되는 작업입니다. 새 트리거나 변경은 채팅의 카드에서 확인할 때까지 대기하며, 일시중지와 재개는 즉시 적용되고 되돌릴 수 있습니다.",
|
||||
"changes": "모델이 메모리 노트나 에이전트의 고정 규칙에 대한 변경을 제안하고, 확인한 변경을 되돌릴 수 있습니다. 채팅의 카드에서 제안을 확인하기 전에는 아무것도 바뀌지 않습니다."
|
||||
"shell": "모델이 셸 명령과 스크립트를 실행할 수 있습니다.",
|
||||
"files": "모델이 내 파일을 나열하고 읽고 쓰고 검색할 수 있습니다.",
|
||||
"web": "모델이 웹을 검색하고 공개 페이지를 읽을 수 있습니다.",
|
||||
"media": "모델이 내 파일의 이미지를 설명하고 녹음을 받아쓸 수 있습니다.",
|
||||
"collections": "모델이 내 컬렉션을 검색할 수 있습니다.",
|
||||
"subagents": "모델이 작업 하나를 위해 하위 에이전트를 시작하고 보고를 받을 수 있습니다.",
|
||||
"saved_agents": "모델이 저장된 에이전트 중 하나를 하위 에이전트로 시작할 수 있습니다.",
|
||||
"triggers": "모델이 트리거를 제안하고, 나열하고, 변경하고, 삭제할 수 있습니다. 새 트리거나 변경은 매번 직접 확인합니다.",
|
||||
"changes": "모델이 내 메모리와 에이전트 파일의 변경을 제안할 수 있습니다. 매번 직접 확인합니다."
|
||||
},
|
||||
"whenOff": {
|
||||
"shell": "모델이 파일은 쓸 수 있지만 아무것도 실행할 수 없습니다.",
|
||||
@@ -352,7 +352,7 @@
|
||||
"collections": "모델이 내 컬렉션을 읽을 수 없습니다.",
|
||||
"subagents": "모델이 혼자 일합니다.",
|
||||
"saved_agents": "모델이 저장된 에이전트를 보거나 시작할 수 없습니다.",
|
||||
"triggers": "모델이 트리거를 만들거나 관리할 수 없습니다. 트리거나 커넥터가 시작한 실행에는 트리거 도구가 없습니다.",
|
||||
"triggers": "모델이 트리거를 제안하거나 관리할 수 없습니다.",
|
||||
"changes": "모델이 메모리나 에이전트 규칙의 변경을 제안할 수 없습니다."
|
||||
},
|
||||
"addonDescribe_one": "이 애드온의 도구 {{count}}개를 모델에 제공합니다.",
|
||||
@@ -360,7 +360,7 @@
|
||||
"serverDescribe": "모델의 MCP 서버입니다. 이 서버의 도구가 모델에 제공됩니다.",
|
||||
"connectorDescribe": "내 MCP 커넥터 중 하나입니다. 이 커넥터의 도구가 모델에 제공됩니다.",
|
||||
"gone": "여기서는 더 이상 사용할 수 없습니다. 끄면 제거됩니다.",
|
||||
"grants": "에이전트가 변경할 수 있는 것",
|
||||
"grants": "기타 권한",
|
||||
"grantSensitive": "민감함: 에이전트가 나중에 할 수 있거나 접근할 수 있는 범위가 바뀝니다.",
|
||||
"connection": {
|
||||
"label": "연결",
|
||||
@@ -374,6 +374,77 @@
|
||||
"agentLabel": "이 에이전트 채팅의 연결",
|
||||
"agentHelp": "이 에이전트의 채팅은 이 연결만 쓸 수 있으며 바꿀 수 없습니다.",
|
||||
"perChatHelp": "선택 안 함: 채팅마다 직접 고릅니다."
|
||||
},
|
||||
"optionNeeds": "이를 사용하려면 “{{name}}”을(를) 켜세요.",
|
||||
"connectionMissing": "{{name}}에서는 아직 허용하지 않습니다.",
|
||||
"connectionOpen": "권한 열기",
|
||||
"section": {
|
||||
"messaging": {
|
||||
"title": "메신저 앱",
|
||||
"intro": "메신저 앱에서 시작되는 채팅에 적용됩니다. 연결도 자체 권한 페이지에서 같은 것을 허용해야 합니다."
|
||||
},
|
||||
"unattended": {
|
||||
"title": "아무도 지켜보지 않을 때",
|
||||
"intro": "트리거나 메신저 앱이 시작한 실행에 적용됩니다. 이런 실행에서는 아무도 단계를 확인할 수 없습니다."
|
||||
}
|
||||
},
|
||||
"grant": {
|
||||
"memory_write": {
|
||||
"title": "기억하기",
|
||||
"description": "모델이 내 메모리 또는 에이전트 자체 메모리에 넣을 메모를 제안할 수 있습니다. 메모마다 직접 확인합니다."
|
||||
},
|
||||
"profile_write": {
|
||||
"title": "자체 규칙 변경",
|
||||
"description": "모델이 에이전트의 고정 규칙 수정을 제안할 수 있습니다. 수정마다 직접 확인합니다."
|
||||
},
|
||||
"skills_write": {
|
||||
"title": "스킬 작성",
|
||||
"description": "모델이 새 스킬이나 변경된 스킬을 제안할 수 있습니다. 하나씩 직접 확인합니다."
|
||||
},
|
||||
"pages_write": {
|
||||
"title": "페이지 만들기",
|
||||
"description": "모델이 격리된 프레임에서 열리는 작은 앱을 제안할 수 있습니다. 직접 확인합니다."
|
||||
},
|
||||
"dashboard_write": {
|
||||
"title": "대시보드 변경",
|
||||
"description": "모델이 홈 대시보드의 새 레이아웃을 제안할 수 있습니다. 변경마다 직접 확인합니다."
|
||||
},
|
||||
"triggers_propose": {
|
||||
"title": "메신저 앱에서도 제안",
|
||||
"description": "누군가 메신저 앱에서 요청하면 모델이 트리거를 제안할 수 있습니다. 직접 확인합니다."
|
||||
},
|
||||
"triggers_run": {
|
||||
"title": "메신저 앱에서 트리거 시작 허용",
|
||||
"description": "메신저 연결에 묶인 트리거가 실행을 시작하고 그곳으로 결과를 전달할 수 있습니다."
|
||||
},
|
||||
"talkback_channels": {
|
||||
"title": "알려진 채널에 답장",
|
||||
"description": "모델이 이미 대화 중인 채널에 메시지를 보낼 수 있습니다."
|
||||
},
|
||||
"talkback_new_channel": {
|
||||
"title": "새 채널 시작",
|
||||
"description": "모델이 아직 쓰지 않은 채널에서 대화를 시작할 수 있습니다."
|
||||
},
|
||||
"files_upload": {
|
||||
"title": "메신저 앱에서 파일 받기",
|
||||
"description": "보낸 사람이 모델이 읽을 파일을 첨부할 수 있습니다. 파일을 밖으로 보낼 수는 없습니다."
|
||||
},
|
||||
"act_files": {
|
||||
"title": "스스로 파일 쓰기",
|
||||
"description": "아무도 지켜보지 않는 실행이 에이전트의 폴더에 파일을 쓸 수 있습니다."
|
||||
},
|
||||
"act_addons": {
|
||||
"title": "스스로 애드온 동작 사용",
|
||||
"description": "아무도 지켜보지 않는 실행이 에이전트 애드온의 동작을 호출할 수 있습니다."
|
||||
},
|
||||
"act_send": {
|
||||
"title": "스스로 메시지 보내기",
|
||||
"description": "아무도 지켜보지 않는 실행이 전달 대상 밖으로 메시지를 보낼 수 있습니다."
|
||||
},
|
||||
"act_spend": {
|
||||
"title": "스스로 유료 또는 외부 도구 사용",
|
||||
"description": "아무도 지켜보지 않는 실행이 유료 또는 외부 도구와 네트워크를 사용할 수 있습니다."
|
||||
}
|
||||
}
|
||||
},
|
||||
"vision": {
|
||||
|
||||
@@ -81,8 +81,7 @@
|
||||
"MCP": "MCP servers",
|
||||
"export": "Export",
|
||||
"Files": "Arquivos",
|
||||
"Tools": "Ferramentas",
|
||||
"Grants": "Permissions"
|
||||
"Tools": "Ferramentas"
|
||||
},
|
||||
"name": "Name",
|
||||
"description": "Description",
|
||||
@@ -137,17 +136,19 @@
|
||||
"all": "Todos os sites públicos"
|
||||
},
|
||||
"toolsSummary": "{{on}} de {{total}} ligadas",
|
||||
"toolsHelp": "Escolha o que um chat com este agente pode usar. São os mesmos interruptores do menu Ferramentas de um chat. Uma ferramenta desligada nunca é oferecida ao modelo, e um chat com este agente não pode ligá-la.",
|
||||
"toolsHelp": "Escolha o que um chat com este agente pode usar. São as mesmas chaves do menu Ferramentas de um chat, com as opções de cada chave abaixo. Uma ferramenta desligada nunca é oferecida ao modelo. Sem nenhuma opção marcada, o agente mantém os padrões das suas conexões de mensagens; ao marcar alguma, só as marcadas funcionam.",
|
||||
"toolsHeading": "Ferramentas deste agente",
|
||||
"skillsLater": "Um chat com este agente lê apenas as skills ligadas.",
|
||||
"skillsHeading": "Skills deste agente",
|
||||
"grantsHelp": "What the agent may do beyond its tools. With no permission ticked, the agent keeps the defaults it had before permissions existed. Once you tick any, only the ticked ones work.",
|
||||
"grantsDefault": "Defaults",
|
||||
"countGrants": "{{count}} granted",
|
||||
"grantSensitive": "needs care",
|
||||
"grantsNoticeTitle": "Some messaging features will turn off.",
|
||||
"grantsNotice": "This agent had no permission list, so it kept these on its messaging connections: {{grants}}. They stop working until you tick them here.",
|
||||
"grantsAddMissing": "Add the missing permissions"
|
||||
"grantsAddMissing": "Add the missing permissions",
|
||||
"grantNames": {
|
||||
"triggers_propose": "Propor também de aplicativos de mensagens",
|
||||
"triggers_run": "Deixar gatilhos começarem de aplicativos de mensagens",
|
||||
"talkback_channels": "Responder em canais conhecidos",
|
||||
"files_upload": "Receber arquivos de aplicativos de mensagens"
|
||||
}
|
||||
},
|
||||
"run": {
|
||||
"workingLine": "Working"
|
||||
|
||||
@@ -141,7 +141,8 @@
|
||||
"failed": "Não foi possível salvar. O interruptor voltou ao que era.",
|
||||
"unavailable": "Indisponível neste chat",
|
||||
"toolCount_one": "{{count}} ferramenta",
|
||||
"toolCount_other": "{{count}} ferramentas"
|
||||
"toolCount_other": "{{count}} ferramentas",
|
||||
"optionsOf": "Opções de {{name}}"
|
||||
},
|
||||
"skills": {
|
||||
"label": "Habilidades",
|
||||
|
||||
@@ -314,7 +314,7 @@
|
||||
"builtin": {
|
||||
"web": "Web",
|
||||
"saved_agents": "Agentes salvos",
|
||||
"triggers": "Gatilhos",
|
||||
"triggers": "Criar e gerenciar gatilhos",
|
||||
"shell": "Executar comandos",
|
||||
"files": "Seus arquivos",
|
||||
"media": "Imagens e áudio",
|
||||
@@ -334,15 +334,15 @@
|
||||
"isolated": "Os comandos rodam isolados"
|
||||
},
|
||||
"describe": {
|
||||
"shell": "O modelo pode executar comandos de shell e scripts. Eles rodam em um add-on que os isola, se houver um instalado; senão, direto nesta máquina.",
|
||||
"files": "O modelo pode listar, ler, escrever, editar, mover, apagar e buscar seus arquivos, e ler documentos. Um chat de um agente que trabalha em uma só pasta alcança apenas essa pasta.",
|
||||
"web": "O modelo pode pesquisar na web e ler uma página pública pelo endereço. Endereços dentro da sua rede são recusados, a menos que um administrador permita.",
|
||||
"media": "O modelo pode descrever uma imagem ou transcrever uma gravação dos seus arquivos com um modelo auxiliar.",
|
||||
"collections": "O modelo pode listar suas coleções e buscar nelas os trechos que respondem a uma pergunta.",
|
||||
"subagents": "O modelo pode iniciar um subagente que trabalha em uma tarefa com os mesmos interruptores deste chat e depois informa o resultado.",
|
||||
"saved_agents": "O modelo pode listar seus agentes salvos e iniciar um como subagente, com as instruções e o modelo desse agente.",
|
||||
"triggers": "O modelo pode propor, listar, alterar e apagar gatilhos: tarefas que rodam sozinhas em um horário definido ou quando um arquivo chega a uma pasta. Um gatilho novo ou uma alteração espera em um cartão no chat até você confirmar; pausar ou retomar um gatilho vale na hora e você pode desfazer.",
|
||||
"changes": "O modelo pode propor uma alteração nas suas notas de memória ou nas regras fixas de um agente, e desfazer uma alteração que você confirmou. Nada muda até você confirmar a proposta em um cartão no chat."
|
||||
"shell": "O modelo pode executar comandos de shell e scripts.",
|
||||
"files": "O modelo pode listar, ler, escrever e pesquisar seus arquivos.",
|
||||
"web": "O modelo pode pesquisar na web e ler páginas públicas.",
|
||||
"media": "O modelo pode descrever imagens e transcrever gravações dos seus arquivos.",
|
||||
"collections": "O modelo pode pesquisar suas coleções.",
|
||||
"subagents": "O modelo pode iniciar um subagente para uma tarefa e receber o relatório dele.",
|
||||
"saved_agents": "O modelo pode iniciar um dos seus agentes salvos como subagente.",
|
||||
"triggers": "O modelo pode propor, listar, alterar e excluir gatilhos. Você confirma cada novo gatilho ou alteração.",
|
||||
"changes": "O modelo pode propor alterações na sua memória e nos arquivos de um agente. Você confirma cada uma."
|
||||
},
|
||||
"whenOff": {
|
||||
"shell": "O modelo pode escrever arquivos, mas não pode executar nada.",
|
||||
@@ -352,7 +352,7 @@
|
||||
"collections": "O modelo não pode ler suas coleções.",
|
||||
"subagents": "O modelo trabalha sozinho.",
|
||||
"saved_agents": "O modelo não pode ver nem iniciar seus agentes salvos.",
|
||||
"triggers": "O modelo não pode criar nem gerenciar gatilhos. Uma execução iniciada por um gatilho ou um conector nunca os tem.",
|
||||
"triggers": "O modelo não pode propor nem gerenciar gatilhos.",
|
||||
"changes": "O modelo não pode propor alterações na sua memória ou nas regras de um agente."
|
||||
},
|
||||
"addonDescribe_one": "Dá ao modelo {{count}} ferramenta deste add-on.",
|
||||
@@ -360,7 +360,7 @@
|
||||
"serverDescribe": "Um servidor MCP do modelo: suas ferramentas são oferecidas ao modelo.",
|
||||
"connectorDescribe": "Um dos seus conectores MCP: suas ferramentas são oferecidas ao modelo.",
|
||||
"gone": "Não está mais disponível aqui. Desligue para removê-lo.",
|
||||
"grants": "O que o agente pode alterar",
|
||||
"grants": "Outras permissões",
|
||||
"grantSensitive": "Sensível: isso muda o que o agente poderá fazer ou acessar depois.",
|
||||
"connection": {
|
||||
"label": "Conexões",
|
||||
@@ -374,6 +374,77 @@
|
||||
"agentLabel": "Conexões para os chats deste agente",
|
||||
"agentHelp": "Os chats deste agente só podem usar estas conexões e não podem alterá-las.",
|
||||
"perChatHelp": "Nenhuma escolhida: cada chat escolhe a sua."
|
||||
},
|
||||
"optionNeeds": "Ative “{{name}}” para usar isto.",
|
||||
"connectionMissing": "{{name}} ainda não permite isto.",
|
||||
"connectionOpen": "Abrir as permissões dela",
|
||||
"section": {
|
||||
"messaging": {
|
||||
"title": "Aplicativos de mensagens",
|
||||
"intro": "Vale para chats que começam em um aplicativo de mensagens. A conexão precisa permitir o mesmo na própria página de permissões."
|
||||
},
|
||||
"unattended": {
|
||||
"title": "Quando ninguém está olhando",
|
||||
"intro": "Vale para execuções iniciadas por um gatilho ou por um aplicativo de mensagens, em que ninguém pode confirmar uma etapa."
|
||||
}
|
||||
},
|
||||
"grant": {
|
||||
"memory_write": {
|
||||
"title": "Lembrar de coisas",
|
||||
"description": "O modelo pode propor uma nota para a sua memória ou a do agente. Você confirma cada nota."
|
||||
},
|
||||
"profile_write": {
|
||||
"title": "Alterar as próprias regras",
|
||||
"description": "O modelo pode propor uma edição nas regras permanentes do agente. Você confirma cada edição."
|
||||
},
|
||||
"skills_write": {
|
||||
"title": "Escrever skills",
|
||||
"description": "O modelo pode propor uma skill nova ou alterada. Você confirma cada uma."
|
||||
},
|
||||
"pages_write": {
|
||||
"title": "Criar páginas",
|
||||
"description": "O modelo pode propor um pequeno app que abre em um quadro isolado. Você o confirma."
|
||||
},
|
||||
"dashboard_write": {
|
||||
"title": "Alterar o painel",
|
||||
"description": "O modelo pode propor um novo layout do seu painel inicial. Você confirma cada alteração."
|
||||
},
|
||||
"triggers_propose": {
|
||||
"title": "Propor também de aplicativos de mensagens",
|
||||
"description": "O modelo pode propor um gatilho quando alguém pede em um aplicativo de mensagens. Você o confirma."
|
||||
},
|
||||
"triggers_run": {
|
||||
"title": "Deixar gatilhos começarem de aplicativos de mensagens",
|
||||
"description": "Um gatilho ligado a uma conexão de mensagens pode iniciar uma execução e entregar o resultado lá."
|
||||
},
|
||||
"talkback_channels": {
|
||||
"title": "Responder em canais conhecidos",
|
||||
"description": "O modelo pode enviar uma mensagem a um canal em que já atua."
|
||||
},
|
||||
"talkback_new_channel": {
|
||||
"title": "Iniciar novos canais",
|
||||
"description": "O modelo pode começar uma conversa em um canal que nunca usou."
|
||||
},
|
||||
"files_upload": {
|
||||
"title": "Receber arquivos de aplicativos de mensagens",
|
||||
"description": "Quem envia pode anexar arquivos para o modelo ler. Ele não pode enviar arquivos."
|
||||
},
|
||||
"act_files": {
|
||||
"title": "Escrever arquivos por conta própria",
|
||||
"description": "Uma execução que ninguém acompanha pode escrever arquivos nas pastas do agente."
|
||||
},
|
||||
"act_addons": {
|
||||
"title": "Usar ações de add-ons por conta própria",
|
||||
"description": "Uma execução que ninguém acompanha pode chamar as ações dos add-ons do agente."
|
||||
},
|
||||
"act_send": {
|
||||
"title": "Enviar mensagens por conta própria",
|
||||
"description": "Uma execução que ninguém acompanha pode enviar mensagens além do seu destino de entrega."
|
||||
},
|
||||
"act_spend": {
|
||||
"title": "Usar ferramentas pagas ou externas por conta própria",
|
||||
"description": "Uma execução que ninguém acompanha pode usar ferramentas pagas ou externas e a rede."
|
||||
}
|
||||
}
|
||||
},
|
||||
"vision": {
|
||||
|
||||
@@ -81,8 +81,7 @@
|
||||
"MCP": "MCP servers",
|
||||
"export": "Export",
|
||||
"Files": "文件",
|
||||
"Tools": "工具",
|
||||
"Grants": "Permissions"
|
||||
"Tools": "工具"
|
||||
},
|
||||
"name": "Name",
|
||||
"description": "Description",
|
||||
@@ -137,17 +136,19 @@
|
||||
"all": "所有公共网站"
|
||||
},
|
||||
"toolsSummary": "{{total}} 项中开启 {{on}} 项",
|
||||
"toolsHelp": "选择使用此智能体的聊天可以用什么。这些开关与聊天的工具菜单相同。关闭的工具不会提供给模型,使用此智能体的聊天也无法将其打开。",
|
||||
"toolsHelp": "选择与此智能体的聊天可以使用什么。这些开关与聊天的工具菜单相同,每个开关的选项在其下方。关闭的工具不会提供给模型。未勾选任何选项时,智能体保留其消息连接的默认设置;一旦勾选任何一项,只有勾选的才生效。",
|
||||
"toolsHeading": "此智能体的工具",
|
||||
"skillsLater": "使用此智能体的聊天只会读取已开启的技能。",
|
||||
"skillsHeading": "此智能体的技能",
|
||||
"grantsHelp": "What the agent may do beyond its tools. With no permission ticked, the agent keeps the defaults it had before permissions existed. Once you tick any, only the ticked ones work.",
|
||||
"grantsDefault": "Defaults",
|
||||
"countGrants": "{{count}} granted",
|
||||
"grantSensitive": "needs care",
|
||||
"grantsNoticeTitle": "Some messaging features will turn off.",
|
||||
"grantsNotice": "This agent had no permission list, so it kept these on its messaging connections: {{grants}}. They stop working until you tick them here.",
|
||||
"grantsAddMissing": "Add the missing permissions"
|
||||
"grantsAddMissing": "Add the missing permissions",
|
||||
"grantNames": {
|
||||
"triggers_propose": "也可从消息应用提议",
|
||||
"triggers_run": "允许触发器从消息应用启动",
|
||||
"talkback_channels": "在已知频道回复",
|
||||
"files_upload": "从消息应用接收文件"
|
||||
}
|
||||
},
|
||||
"run": {
|
||||
"workingLine": "Working"
|
||||
|
||||
@@ -138,7 +138,8 @@
|
||||
"failed": "无法保存。开关已恢复原状。",
|
||||
"unavailable": "此对话中不可用",
|
||||
"toolCount_one": "{{count}} 个工具",
|
||||
"toolCount_other": "{{count}} 个工具"
|
||||
"toolCount_other": "{{count}} 个工具",
|
||||
"optionsOf": "{{name}}的选项"
|
||||
},
|
||||
"skills": {
|
||||
"label": "技能",
|
||||
|
||||
@@ -314,7 +314,7 @@
|
||||
"builtin": {
|
||||
"web": "网页",
|
||||
"saved_agents": "已保存的智能体",
|
||||
"triggers": "触发器",
|
||||
"triggers": "创建和管理触发器",
|
||||
"shell": "运行命令",
|
||||
"files": "你的文件",
|
||||
"media": "图片和音频",
|
||||
@@ -334,15 +334,15 @@
|
||||
"isolated": "命令在隔离环境中运行"
|
||||
},
|
||||
"describe": {
|
||||
"shell": "模型可以运行 shell 命令和脚本。若已安装能隔离命令的附加组件,命令在其中运行;否则直接在这台机器上运行。",
|
||||
"files": "模型可以列出、读取、写入、编辑、移动、删除和搜索你的文件,并读取文档。只在一个文件夹中工作的智能体,其聊天只能访问该文件夹。",
|
||||
"web": "模型可以搜索网页,并通过地址读取公开页面。你网络内部的地址会被拒绝,除非管理员允许。",
|
||||
"media": "模型可以用辅助模型描述你文件中的图片,或转写其中的录音。",
|
||||
"collections": "模型可以列出你的集合,并在其中搜索与问题匹配的段落。",
|
||||
"subagents": "模型可以启动一个子智能体,用与本聊天相同的开关处理一项任务并汇报结果。",
|
||||
"saved_agents": "模型可以列出你保存的智能体,并将其中一个作为子智能体启动,使用该智能体自己的指令和模型。",
|
||||
"triggers": "模型可以提议、列出、修改和删除触发器:在设定时间或有文件到达文件夹时自动运行的任务。新触发器或修改会在聊天的卡片上等待你确认;暂停或恢复触发器立即生效,且可以撤销。",
|
||||
"changes": "模型可以提议修改你的记忆笔记或智能体的固定规则,并撤销你已确认的修改。在你于聊天的卡片上确认提议之前,不会有任何改变。"
|
||||
"shell": "模型可以运行 shell 命令和脚本。",
|
||||
"files": "模型可以列出、读取、写入和搜索你的文件。",
|
||||
"web": "模型可以搜索网页并读取公开页面。",
|
||||
"media": "模型可以描述图片,并转写你文件中的录音。",
|
||||
"collections": "模型可以搜索你的集合。",
|
||||
"subagents": "模型可以为一项任务启动子智能体并获取其报告。",
|
||||
"saved_agents": "模型可以把你已保存的智能体之一作为子智能体启动。",
|
||||
"triggers": "模型可以提议、列出、修改和删除触发器。每个新触发器或修改都由你确认。",
|
||||
"changes": "模型可以提议修改你的记忆和智能体的文件。每一项都由你确认。"
|
||||
},
|
||||
"whenOff": {
|
||||
"shell": "模型可以写文件,但不能运行任何东西。",
|
||||
@@ -352,7 +352,7 @@
|
||||
"collections": "模型无法读取你的集合。",
|
||||
"subagents": "模型独自工作。",
|
||||
"saved_agents": "模型看不到也无法启动你保存的智能体。",
|
||||
"triggers": "模型无法创建或管理触发器。由触发器或连接器启动的运行永远没有这些工具。",
|
||||
"triggers": "模型无法提议或管理触发器。",
|
||||
"changes": "模型无法提议修改你的记忆或智能体的规则。"
|
||||
},
|
||||
"addonDescribe_one": "向模型提供此附加组件的 {{count}} 个工具。",
|
||||
@@ -360,7 +360,7 @@
|
||||
"serverDescribe": "模型的一个 MCP 服务器:其工具会提供给模型。",
|
||||
"connectorDescribe": "你的 MCP 连接器之一:其工具会提供给模型。",
|
||||
"gone": "此处已不可用。关闭它即可移除。",
|
||||
"grants": "智能体可以更改的内容",
|
||||
"grants": "其他权限",
|
||||
"grantSensitive": "敏感:这会改变智能体之后可以做或可以访问的内容。",
|
||||
"connection": {
|
||||
"label": "连接",
|
||||
@@ -374,6 +374,77 @@
|
||||
"agentLabel": "此智能体的聊天可用的连接",
|
||||
"agentHelp": "此智能体的聊天只能使用这些连接,且不能更改。",
|
||||
"perChatHelp": "未选择:每个聊天自行选择。"
|
||||
},
|
||||
"optionNeeds": "打开“{{name}}”才能使用此项。",
|
||||
"connectionMissing": "{{name}} 尚未允许此项。",
|
||||
"connectionOpen": "打开其权限",
|
||||
"section": {
|
||||
"messaging": {
|
||||
"title": "消息应用",
|
||||
"intro": "适用于从消息应用开始的聊天。该连接必须在自己的权限页面允许同样的事。"
|
||||
},
|
||||
"unattended": {
|
||||
"title": "无人看管时",
|
||||
"intro": "适用于由触发器或消息应用启动的运行,这类运行中无人能确认某一步。"
|
||||
}
|
||||
},
|
||||
"grant": {
|
||||
"memory_write": {
|
||||
"title": "记住事情",
|
||||
"description": "模型可以提议一条笔记,存入你的记忆或智能体自己的记忆。每条笔记由你确认。"
|
||||
},
|
||||
"profile_write": {
|
||||
"title": "修改自身规则",
|
||||
"description": "模型可以提议修改智能体的长期规则。每次修改由你确认。"
|
||||
},
|
||||
"skills_write": {
|
||||
"title": "编写技能",
|
||||
"description": "模型可以提议新的或修改后的技能。每一项由你确认。"
|
||||
},
|
||||
"pages_write": {
|
||||
"title": "创建页面",
|
||||
"description": "模型可以提议一个在沙箱框架中打开的小应用。由你确认。"
|
||||
},
|
||||
"dashboard_write": {
|
||||
"title": "修改仪表板",
|
||||
"description": "模型可以提议你首页仪表板的新布局。每次修改由你确认。"
|
||||
},
|
||||
"triggers_propose": {
|
||||
"title": "也可从消息应用提议",
|
||||
"description": "有人在消息应用中提出请求时,模型可以提议触发器。由你确认。"
|
||||
},
|
||||
"triggers_run": {
|
||||
"title": "允许触发器从消息应用启动",
|
||||
"description": "绑定到消息连接的触发器可以启动运行,并把结果送到那里。"
|
||||
},
|
||||
"talkback_channels": {
|
||||
"title": "在已知频道回复",
|
||||
"description": "模型可以向它已在其中交流的频道发送消息。"
|
||||
},
|
||||
"talkback_new_channel": {
|
||||
"title": "开启新频道",
|
||||
"description": "模型可以在它从未用过的频道上开始对话。"
|
||||
},
|
||||
"files_upload": {
|
||||
"title": "从消息应用接收文件",
|
||||
"description": "发送者可以附上文件供模型读取。模型不能向外发送文件。"
|
||||
},
|
||||
"act_files": {
|
||||
"title": "自行写入文件",
|
||||
"description": "无人看管的运行可以在智能体的文件夹中写入文件。"
|
||||
},
|
||||
"act_addons": {
|
||||
"title": "自行使用插件动作",
|
||||
"description": "无人看管的运行可以调用智能体插件的动作。"
|
||||
},
|
||||
"act_send": {
|
||||
"title": "自行发送消息",
|
||||
"description": "无人看管的运行可以在其投递目标之外发送消息。"
|
||||
},
|
||||
"act_spend": {
|
||||
"title": "自行使用付费或外部工具",
|
||||
"description": "无人看管的运行可以使用付费或外部工具以及网络。"
|
||||
}
|
||||
}
|
||||
},
|
||||
"vision": {
|
||||
|
||||
@@ -93,7 +93,7 @@ export function BulkActions({ onAll, onNone, allDisabled, noneDisabled, allLabel
|
||||
|
||||
// A group of rows under a heading with its icon, its count and, when it has
|
||||
// more than one switch, its own actions.
|
||||
export function SwitchGroup({ title, icon, count, actions, testId, children }) {
|
||||
export function SwitchGroup({ title, icon, count, actions, intro, testId, children }) {
|
||||
const headId = useId()
|
||||
return (
|
||||
<section className="swl-group" aria-labelledby={headId} data-testid={testId}>
|
||||
@@ -103,6 +103,7 @@ export function SwitchGroup({ title, icon, count, actions, testId, children }) {
|
||||
{count && <span className="swl-group__count">{count}</span>}
|
||||
{actions}
|
||||
</div>
|
||||
{intro && <p className="swl-group__intro">{intro}</p>}
|
||||
{children}
|
||||
</section>
|
||||
)
|
||||
@@ -127,7 +128,7 @@ export function SwitchGroup({ title, icon, count, actions, testId, children }) {
|
||||
// sits outside the label, so using it never toggles the switch
|
||||
export function SwitchRow({
|
||||
name, blurb, desc, tone, chip, chipTestId, meta, metaTestId, metaKind, reason, title, checked, disabled = false, onChange,
|
||||
stacked = false, testId, descTestId, blurbTestId, data = {}, extra,
|
||||
stacked = false, testId, descTestId, blurbTestId, data = {}, extra, extraId, nested = false,
|
||||
}) {
|
||||
const nameId = useId()
|
||||
const descId = useId()
|
||||
@@ -137,7 +138,7 @@ export function SwitchRow({
|
||||
const attrs = Object.fromEntries(Object.entries(data).map(([k, v]) => [`data-${k}`, v]))
|
||||
const row = (
|
||||
<div
|
||||
className={`swl-row${stacked || blurb ? ' swl-row--stacked' : ''}${extra ? ' swl-row--extended' : ''}`}
|
||||
className={`swl-row${nested ? ' swl-row--option' : ''}${stacked || blurb ? ' swl-row--stacked' : ''}${extra ? ' swl-row--extended' : ''}`}
|
||||
data-on={checked ? 'true' : 'false'}
|
||||
data-disabled={disabled ? 'true' : undefined}
|
||||
title={title}
|
||||
@@ -164,7 +165,7 @@ export function SwitchRow({
|
||||
checked={checked}
|
||||
disabled={disabled}
|
||||
labelledBy={nameId}
|
||||
describedBy={line ? descId : undefined}
|
||||
describedBy={[line ? descId : '', extraId || ''].filter(Boolean).join(' ') || undefined}
|
||||
onChange={onChange}
|
||||
/>
|
||||
</div>
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
import { useId, useState } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { Link } from 'react-router-dom'
|
||||
import Icon from '../Icon'
|
||||
import { BulkActions, SwitchGroup, SwitchHead, SwitchPopover, SwitchRow, SwitchStatus } from './SwitchList'
|
||||
import { bulkIds, bulkable, rowOn, switchCounts, switchRows } from '../../utils/chatSwitchRows'
|
||||
|
||||
@@ -101,6 +102,7 @@ export function SwitchPanel({ heading, note, noteId, notice, groups, error, foot
|
||||
key={g.key}
|
||||
title={g.title}
|
||||
icon={g.icon}
|
||||
intro={g.intro}
|
||||
count={titled ? t('tools.groupCount', { on: c.on, total: c.total }) : null}
|
||||
actions={titled && g.onSet && bulkable(g.rows) > 1 ? actionsFor([g], true, g.title) : null}
|
||||
testId={`${testId}-group-${g.key}`}
|
||||
@@ -115,10 +117,24 @@ export function SwitchPanel({ heading, note, noteId, notice, groups, error, foot
|
||||
)
|
||||
}
|
||||
|
||||
function ToolRow({ row: r, testId }) {
|
||||
function ToolRow({ row: r, testId, nested = false }) {
|
||||
const { t } = useTranslation('chat')
|
||||
const notesId = useId()
|
||||
const usable = r.usable !== false
|
||||
const reason = !usable ? (r.reason || t('tools.unavailable')) : ''
|
||||
// An option is greyed while the switch above it is off; its reason says so.
|
||||
const reason = !usable ? (r.reason || t('tools.unavailable')) : (r.blocked ? r.reason : '')
|
||||
const hasNotes = (r.notes || []).length > 0
|
||||
const extra = (r.pick || hasNotes || (r.options || []).length > 0) ? (
|
||||
<>
|
||||
{r.pick && <RowPick pick={r.pick} testId={testId} />}
|
||||
{hasNotes && <RowNotes notes={r.notes} id={notesId} testId={testId} />}
|
||||
{(r.options || []).length > 0 && (
|
||||
<div className="swl-options" role="group" aria-label={t('tools.optionsOf', { name: r.label })} data-testid={`${testId}-options`}>
|
||||
{r.options.map((o) => <ToolRow key={o.key} row={o} testId={testId} nested />)}
|
||||
</div>
|
||||
)}
|
||||
</>
|
||||
) : undefined
|
||||
const desc = r.note || (r.optIn && usable ? t('tools.optIn') : '')
|
||||
const on = rowOn(r)
|
||||
// What the switch does, and, once it is off, what the model loses.
|
||||
@@ -136,17 +152,34 @@ function ToolRow({ row: r, testId }) {
|
||||
reason={reason}
|
||||
title={r.title}
|
||||
checked={rowOn(r)}
|
||||
disabled={!usable || !!r.readOnly}
|
||||
disabled={!usable || !!r.readOnly || !!r.blocked}
|
||||
onChange={(next) => r.onToggle(next)}
|
||||
stacked={!!(reason || desc)}
|
||||
testId={`${testId}-item`}
|
||||
descTestId={r.note ? `${testId}-note` : undefined}
|
||||
data={{ optin: r.optIn ? 'true' : undefined }}
|
||||
extra={r.pick ? <RowPick pick={r.pick} testId={testId} /> : undefined}
|
||||
extra={extra}
|
||||
extraId={hasNotes ? notesId : undefined}
|
||||
nested={nested}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
// What a messaging connection of the agent does not allow yet, under the
|
||||
// option that needs it, with a link to the page of that connection.
|
||||
function RowNotes({ notes, id, testId }) {
|
||||
return (
|
||||
<ul className="swl-notes" id={id} data-testid={`${testId}-conn-notes`}>
|
||||
{notes.map((n) => (
|
||||
<li key={n.key} className="swl-notes__item" data-testid={`${testId}-conn-note`}>
|
||||
<Icon name="warning" className="swl-notes__icon" />
|
||||
<span>{n.text} <Link className="swl-pick__link" to={n.link.to}>{n.link.label}</Link></span>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
)
|
||||
}
|
||||
|
||||
// A multiple choice under a row, with its name, a description of what it does
|
||||
// and, when there is nothing to choose from, a link to where to make one. The
|
||||
// Tools menu of a chat and the agent form draw it the same way. Each option is
|
||||
|
||||
@@ -196,3 +196,22 @@
|
||||
.swl-pick__option { display: flex; align-items: center; gap: var(--sp-2); font-size: var(--fs-small); color: var(--color-text-primary); cursor: pointer; }
|
||||
.swl-pick__option input { margin: 0; }
|
||||
.swl-pick__link { font-size: var(--fs-meta); }
|
||||
|
||||
/* The options of a switch: grants that refine it, indented under it. A greyed
|
||||
option keeps its place and says why in its reason line. */
|
||||
.swl-options {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
margin: 0 0 0 var(--sp-2);
|
||||
border-left: 2px solid var(--color-border-divider);
|
||||
}
|
||||
.swl-row--option { padding-right: 0; }
|
||||
.swl-row--option[data-disabled="true"] { opacity: 0.7; }
|
||||
.swl-row--option .swl-row__name { font-size: var(--fs-small); font-weight: 450; white-space: normal; overflow: visible; text-overflow: clip; }
|
||||
.swl-group__intro { margin: 0; padding: var(--sp-1) var(--sp-3) var(--sp-2); font-size: var(--fs-meta); line-height: 1.4; color: var(--color-text-secondary); }
|
||||
.swl-notes { list-style: none; margin: 0; padding: 0 0 var(--sp-1); display: flex; flex-direction: column; gap: 2px; }
|
||||
.swl-notes__item { display: flex; align-items: flex-start; gap: var(--sp-1); font-size: var(--fs-meta); line-height: 1.4; color: var(--color-warning); }
|
||||
.swl-notes__item > span { color: var(--color-text-secondary); min-width: 0; overflow-wrap: anywhere; }
|
||||
.swl-notes__icon { flex: none; margin-top: 2px; color: var(--color-warning); }
|
||||
.swl-rowbox:has(.swl-options):hover { background: none; }
|
||||
.swl-options .swl-rowbox:hover { background: var(--color-bg-hover); }
|
||||
+19
-3
@@ -1,8 +1,9 @@
|
||||
import { useCallback, useEffect, useMemo, useState } from 'react'
|
||||
import { chatSkillsApi, chatToolsApi } from '../utils/api'
|
||||
import { chatConnectorsApi, chatSkillsApi, chatToolsApi } from '../utils/api'
|
||||
import { agentConnections } from '../utils/toolOptions'
|
||||
import { pickerSkills } from '../utils/chatSkills'
|
||||
import { useBuiltinGrants } from './useBuiltinGrants'
|
||||
import { addonsAfter, agentAddons, agentGrants, grantsAfter, agentBuiltins, agentConnectors, agentSkills, builtinsAfter, connectionsAfter, connectorsAfter, skillsAfter } from '../utils/agentTools'
|
||||
import { addonsAfter, agentAddons, agentGrants, grantsAfter, agentBuiltins, agentConnectors, agentSkills, builtinsAfter, connectionsAfter, connectorsAfter, savedAgentsGrantAfter, skillsAfter } from '../utils/agentTools'
|
||||
|
||||
// The Tools list of the agent form. It reads what a new chat on the agent's
|
||||
// model could use (the draft lists, the ones the Tools menu of a new chat
|
||||
@@ -18,6 +19,7 @@ export function useAgentTools(form, update) {
|
||||
const [skillList, setSkillList] = useState([])
|
||||
const [replaced, setReplaced] = useState([])
|
||||
const [error, setError] = useState('')
|
||||
const [messaging, setMessaging] = useState({ bindings: [], kinds: [] })
|
||||
|
||||
useEffect(() => {
|
||||
let live = true
|
||||
@@ -40,6 +42,18 @@ export function useAgentTools(form, update) {
|
||||
return () => { live = false }
|
||||
}, [])
|
||||
|
||||
// The messaging connections of a saved agent, read best effort: a server with
|
||||
// connectors off, or an agent not saved yet, has none.
|
||||
const agentId = form.id || ''
|
||||
useEffect(() => {
|
||||
if (!agentId) { setMessaging({ bindings: [], kinds: [] }); return undefined }
|
||||
let live = true
|
||||
Promise.all([chatConnectorsApi.list().catch(() => null), chatConnectorsApi.kinds().catch(() => null)])
|
||||
.then(([b, k]) => { if (live) setMessaging({ bindings: b?.connectors || [], kinds: k?.kinds || [] }) })
|
||||
return () => { live = false }
|
||||
}, [agentId])
|
||||
const connections = useMemo(() => agentConnections(messaging.bindings, messaging.kinds, agentId), [messaging, agentId])
|
||||
|
||||
const builtins = useMemo(() => agentBuiltins(panel.builtins, form), [panel.builtins, form])
|
||||
const addons = useMemo(() => agentAddons(panel.addons, form), [panel.addons, form])
|
||||
const connectors = useMemo(() => agentConnectors(panel.connectors, form), [panel.connectors, form])
|
||||
@@ -51,6 +65,8 @@ export function useAgentTools(form, update) {
|
||||
const next = builtinsAfter(form, panel.builtins, groups, on)
|
||||
update('builtins_off', next.builtins_off)
|
||||
update('builtins_on', next.builtins_on)
|
||||
const grants = savedAgentsGrantAfter(form, groups, on)
|
||||
if (grants.length !== (form.builtins || []).length) update('builtins', grants)
|
||||
}, [form, panel.builtins, update])
|
||||
const setAddonsOn = useCallback(async (ids, on) => { update('addons', addonsAfter(form, ids, on)) }, [form, update])
|
||||
const setMCPOn = useCallback(async (keys, on) => { update('mcp_servers', connectorsAfter(form, keys, on)) }, [form, update])
|
||||
@@ -62,7 +78,7 @@ export function useAgentTools(form, update) {
|
||||
// The grants are rows with their own switch each: no bulk setter, so a
|
||||
// click on Select all never grants a sensitive right.
|
||||
grants: grantList.length > 0 ? { list: grantList, editable: true, onToggle: (name, on) => setGrantsOn([name], on) } : null,
|
||||
builtins, addons, servers: [], connectors, skills, replacedSkills: replaced, error, skillsError: '',
|
||||
builtins, addons, servers: [], connectors, connections, skills, replacedSkills: replaced, error, skillsError: '',
|
||||
toggleBuiltin: (g, on) => setBuiltinsOn([g], on),
|
||||
toggleAddon: (id, on) => setAddonsOn([id], on),
|
||||
toggleMCP: (key, on) => setMCPOn([key], on),
|
||||
|
||||
+38
-12
@@ -1,6 +1,7 @@
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { connectorRef } from '../utils/chatMCP'
|
||||
import { unknownTextKey } from '../utils/chatCommands'
|
||||
import { GRANT_SECTIONS, connectionsMissing, grantKey, placeGrants } from '../utils/toolOptions'
|
||||
|
||||
// The groups of the Tools list, built from the lists of the switches
|
||||
// (useChatSwitches for a chat, useAgentTools for a saved agent). The Tools
|
||||
@@ -80,23 +81,48 @@ export function useToolGroups(switches, { commandsInfo = null, commandState = tr
|
||||
on: !b.off, usable: b.usable, reason: b.reason, onToggle: (on) => switches.toggleBuiltin(b.group, on),
|
||||
...(b.group === SHELL ? shellNote(b) : builtinNote(b)),
|
||||
})
|
||||
// A built-in row with the options that refine it.
|
||||
const withOptions = (row) => {
|
||||
const own = placed.byGroup[row.id]
|
||||
if (!own || own.length === 0) return row
|
||||
const parent = { on: row.on && row.usable !== false, label: row.label }
|
||||
return { ...row, options: own.map((x) => grantRow(x, parent)) }
|
||||
}
|
||||
|
||||
// The builtin grants of a saved agent: what the agent may ask to change
|
||||
// (memory, its profile, skills, pages...). Each row says in plain words what
|
||||
// the right allows, and a sensitive one says so. No onSet: Select all must
|
||||
// never grant a right. The agent form edits them; a chat shows what its
|
||||
// agent holds, read only.
|
||||
// The grants of a saved agent (what it may change, reach or do on its own).
|
||||
// Each one is shown once. A grant that refines a built-in switch sits under
|
||||
// that switch as an option; the rest go in a section of their own. A grant
|
||||
// is greyed, with the reason, while the switch above it is off: its stored
|
||||
// value stays as it is, so it comes back as it was. The agent form edits
|
||||
// them; a chat shows what its agent holds, read only. No onSet anywhere:
|
||||
// Select all must never grant a right.
|
||||
const g = switches.grants
|
||||
const grantsGroup = {
|
||||
key: 'grants', title: tc('tools.grants'), icon: 'shield', rows: (g?.list || []).map((x) => ({
|
||||
const connections = switches.connections || []
|
||||
const builtinList = switches.builtins || []
|
||||
const placed = placeGrants(g?.list, builtinList.map((b) => b.group))
|
||||
const grantRow = (x, parent) => {
|
||||
const k = grantKey(x.name)
|
||||
const blocked = !!parent && !parent.on
|
||||
const missing = x.on && !x.gone && !blocked ? connectionsMissing(x.name, connections) : []
|
||||
return {
|
||||
key: `g-${x.name}`, id: x.name,
|
||||
label: tc(`tools.grant.${x.name.replace(/\./g, '_')}.title`, { defaultValue: x.title || x.name }),
|
||||
description: x.gone ? '' : tc(`tools.grant.${x.name.replace(/\./g, '_')}.description`, { defaultValue: x.description || '' }),
|
||||
label: x.gone ? x.name : tc(`tools.grant.${k}.title`, { defaultValue: x.title || x.name }),
|
||||
description: x.gone ? '' : tc(`tools.grant.${k}.description`, { defaultValue: x.description || '' }),
|
||||
note: x.gone ? tc('tools.gone') : (x.sensitive ? tc('tools.grantSensitive') : ''),
|
||||
warn: !!x.sensitive && !x.gone,
|
||||
blocked, reason: blocked ? tc('tools.optionNeeds', { name: parent.label }) : '',
|
||||
notes: missing.map((c) => ({ key: c.id, text: tc('tools.connectionMissing', { name: c.name }), link: { to: c.to, label: tc('tools.connectionOpen') } })),
|
||||
on: x.on, readOnly: !g.editable, onToggle: (on) => g.onToggle?.(x.name, on),
|
||||
})),
|
||||
}
|
||||
}
|
||||
const sectionGroup = (s) => ({
|
||||
key: s.key, title: tc(`tools.section.${s.key}.title`), icon: s.icon, intro: tc(`tools.section.${s.key}.intro`),
|
||||
rows: (placed.bySection[s.key] || []).map((x) => grantRow(x)),
|
||||
})
|
||||
const grantGroups = [
|
||||
...GRANT_SECTIONS.map(sectionGroup),
|
||||
{ key: 'grants', title: tc('tools.grants'), icon: 'shield', rows: placed.other.map((x) => grantRow(x)) },
|
||||
]
|
||||
|
||||
// The connections an add-on that runs with a credential may use. The host
|
||||
// picks none for the person: with one it is enabled, with several the person
|
||||
@@ -145,9 +171,8 @@ export function useToolGroups(switches, { commandsInfo = null, commandState = tr
|
||||
{
|
||||
// The tools LocalAI serves itself, such as web search: one switch per group.
|
||||
key: 'builtins', title: tc('tools.builtins'), icon: 'globe', onSet: switches.setBuiltinsOn,
|
||||
rows: [...switches.builtins].sort((a, b) => builtinRank(a.group) - builtinRank(b.group)).map(builtinRow),
|
||||
rows: [...builtinList].sort((a, b) => builtinRank(a.group) - builtinRank(b.group)).map((b) => withOptions(builtinRow(b))),
|
||||
},
|
||||
grantsGroup,
|
||||
{
|
||||
// An add-on shows the title and the description its manifest declares.
|
||||
key: 'addons', title: tc('tools.addons'), icon: 'puzzle', onSet: switches.setAddonsOn,
|
||||
@@ -173,6 +198,7 @@ export function useToolGroups(switches, { commandsInfo = null, commandState = tr
|
||||
note: c.gone ? tc('tools.gone') : (c.hint || ''), on: !c.off, usable: c.usable, reason: c.reason, onToggle: (on) => switches.toggleMCP(connectorRef(c.id), on),
|
||||
})),
|
||||
},
|
||||
...grantGroups,
|
||||
]
|
||||
return groups
|
||||
}
|
||||
@@ -27,7 +27,7 @@ import { Button, Callout, LoadError, Page, PageHeader, Segmented, SkeletonRows }
|
||||
import AgentFolderDialog from '../components/agents/AgentFolderDialog'
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
import { SwitchPanel } from '../components/chat/SwitchMenu'
|
||||
import { switchCounts } from '../utils/chatSwitchRows'
|
||||
import { switchCounts, switchRows } from '../utils/chatSwitchRows'
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
import { SkillsPanel } from '../components/chat/SkillsMenu'
|
||||
|
||||
@@ -40,7 +40,6 @@ const SECTIONS = [
|
||||
{ id: 'MemorySettings', icon: 'database' },
|
||||
{ id: 'Skills', icon: 'sparkles' },
|
||||
{ id: 'Tools', icon: 'plug' },
|
||||
{ id: 'Grants', icon: 'shield' },
|
||||
{ id: 'MCP', icon: 'server' },
|
||||
]
|
||||
|
||||
@@ -80,7 +79,6 @@ export default function AgentCreate() {
|
||||
const initialFormRef = useRef(null)
|
||||
const [collectionNames, setCollectionNames] = useState([])
|
||||
const [modelServers, setModelServers] = useState([])
|
||||
const [grantList, setGrantList] = useState([])
|
||||
|
||||
// Suggestions are best effort: a failure leaves the field free text.
|
||||
useEffect(() => {
|
||||
@@ -89,13 +87,6 @@ export default function AgentCreate() {
|
||||
.catch(() => {})
|
||||
}, [])
|
||||
|
||||
// The grants the editor can list: best effort, an empty list hides the checklist.
|
||||
useEffect(() => {
|
||||
chatAgentsApi.builtinGrants()
|
||||
.then(r => setGrantList(Array.isArray(r?.grants) ? r.grants : []))
|
||||
.catch(() => {})
|
||||
}, [])
|
||||
|
||||
// The servers of the fixed model are suggestions; with no fixed model the field is free text.
|
||||
const fixedModel = form.model || ''
|
||||
useEffect(() => {
|
||||
@@ -218,17 +209,11 @@ export default function AgentCreate() {
|
||||
if (s.id === 'MemorySettings') { keys = ['collections']; summary = countOf(form.collections.length, 'create.countCollections'); state = form.collections.length ? 'ready' : 'empty' }
|
||||
else if (s.id === 'Skills') { keys = ['skills']; summary = countOf(form.skills.length, 'create.countSkills'); state = form.skills.length ? 'ready' : 'empty' }
|
||||
else if (s.id === 'Tools') {
|
||||
keys = ['builtins_off', 'builtins_on', 'addons', 'mcp_servers', 'network', 'connections']
|
||||
const { on, total } = switchCounts(toolGroups.flatMap(g => g.rows))
|
||||
keys = ['builtins_off', 'builtins_on', 'builtins', 'addons', 'mcp_servers', 'network', 'connections']
|
||||
const { on, total } = switchCounts(switchRows(toolGroups))
|
||||
summary = total ? t('create.toolsSummary', { on, total }) : t('create.noneYet')
|
||||
state = on ? 'ready' : 'empty'
|
||||
}
|
||||
else if (s.id === 'Grants') {
|
||||
keys = ['builtins']
|
||||
const n = (form.builtins || []).length
|
||||
summary = n ? t('create.countGrants', { count: n }) : t('create.grantsDefault')
|
||||
state = missingGrants.length ? 'needs' : 'ready'
|
||||
}
|
||||
else if (s.id === 'Files') { keys = ['folders']; ({ summary, state } = folderFold()) }
|
||||
else if (s.id === 'MCP') { keys = ['mcp_servers']; summary = countOf(form.mcp_servers.length, 'create.countServers'); state = form.mcp_servers.length ? 'ready' : 'empty' }
|
||||
else {
|
||||
@@ -347,6 +332,15 @@ export default function AgentCreate() {
|
||||
return (
|
||||
<>
|
||||
<p className="ag-note">{t('create.toolsHelp')}</p>
|
||||
{missingGrants.length > 0 && (
|
||||
<Callout
|
||||
tone="warn" testId="agent-grants-notice"
|
||||
title={t('create.grantsNoticeTitle')}
|
||||
actions={<Button size="sm" onClick={() => updateField('builtins', missingGrants.reduce((l, g) => setGrant(l, g, true), form.builtins || []))} data-testid="agent-grants-add-missing">{t('create.grantsAddMissing')}</Button>}
|
||||
>
|
||||
{t('create.grantsNotice', { grants: missingGrants.map(g => t(`create.grantNames.${g.replace(/\./g, '_')}`, { defaultValue: g })).join(', ') })}
|
||||
</Callout>
|
||||
)}
|
||||
<div className="ag-switches" data-testid="agent-tools-panel">
|
||||
<SwitchPanel
|
||||
heading={t('create.toolsHeading')} groups={toolGroups} error={tools.error} testId="agent-tools"
|
||||
@@ -362,32 +356,6 @@ export default function AgentCreate() {
|
||||
</div>
|
||||
</>
|
||||
)
|
||||
case 'Grants':
|
||||
return (
|
||||
<>
|
||||
<p className="ag-note">{t('create.grantsHelp')}</p>
|
||||
{missingGrants.length > 0 && (
|
||||
<Callout
|
||||
tone="warn" testId="agent-grants-notice"
|
||||
title={t('create.grantsNoticeTitle')}
|
||||
actions={<Button size="sm" onClick={() => updateField('builtins', missingGrants.reduce((l, g) => setGrant(l, g, true), form.builtins || []))} data-testid="agent-grants-add-missing">{t('create.grantsAddMissing')}</Button>}
|
||||
>
|
||||
{t('create.grantsNotice', { grants: missingGrants.join(', ') })}
|
||||
</Callout>
|
||||
)}
|
||||
<div className="ag-grants" data-testid="agent-grants">
|
||||
{grantList.map(g => (
|
||||
<label key={g.name} className="ag-grants__row" data-testid="agent-grant">
|
||||
<input type="checkbox" checked={(form.builtins || []).includes(g.name)} onChange={(e) => updateField('builtins', setGrant(form.builtins, g.name, e.target.checked))} />
|
||||
<span className="ag-grants__text">
|
||||
<span className="ag-grants__title">{g.title}{g.sensitive && <span className="ag-grants__tag">{t('create.grantSensitive')}</span>}</span>
|
||||
<span className="ag-note">{g.description}</span>
|
||||
</span>
|
||||
</label>
|
||||
))}
|
||||
</div>
|
||||
</>
|
||||
)
|
||||
case 'Files': {
|
||||
const rows = form.folders || []
|
||||
const effective = effectiveModes(rows)
|
||||
|
||||
+16
-1
@@ -1,5 +1,6 @@
|
||||
import { PREFIX, splitAgentMCP, joinAgentMCP } from './chatMCP.js'
|
||||
import { skillKey } from './chatSkills.js'
|
||||
import { SAVED_AGENTS_GROUP, savedAgentsOn } from './toolOptions.js'
|
||||
|
||||
// A saved agent holds its tools as grants (add-ons, MCP servers, connectors,
|
||||
// skills: what is listed is on) and as switches of the built-in groups
|
||||
@@ -16,7 +17,10 @@ const list = (x) => (Array.isArray(x) ? x : [])
|
||||
export function agentBuiltins(groups, form) {
|
||||
const off = new Set(list(form.builtins_off))
|
||||
const on = new Set(list(form.builtins_on))
|
||||
return list(groups).map((b) => ({ ...b, off: b.opt_in ? !on.has(b.group) : off.has(b.group) }))
|
||||
// Saved agents is one switch with two stored values: the opt-in group and the
|
||||
// grant of the same name. Either one turns it on, as the server does at save.
|
||||
const savedOn = savedAgentsOn(form)
|
||||
return list(groups).map((b) => ({ ...b, off: b.group === SAVED_AGENTS_GROUP ? !savedOn : b.opt_in ? !on.has(b.group) : off.has(b.group) }))
|
||||
}
|
||||
|
||||
// The builtins_off and builtins_on of the form after these groups are switched
|
||||
@@ -37,6 +41,17 @@ export function builtinsAfter(form, groups, names, on) {
|
||||
return { builtins_off: dedupe(off), builtins_on: dedupe(onList) }
|
||||
}
|
||||
|
||||
// The grant that goes with the saved-agents switch. The switch wins: turning
|
||||
// it off takes the grant away too (else the server would turn the group back
|
||||
// on at save). Turning it on adds only the group, never the grant, because the
|
||||
// first grant of an agent turns off what it does by default on its messaging
|
||||
// connections; an agent that already holds the grant keeps it.
|
||||
export function savedAgentsGrantAfter(form, names, on) {
|
||||
const builtins = list(form.builtins)
|
||||
if (on || !names.includes(SAVED_AGENTS_GROUP)) return builtins
|
||||
return builtins.filter((g) => g !== SAVED_AGENTS_GROUP)
|
||||
}
|
||||
|
||||
const dedupe = (l) => l.filter((x, i) => l.indexOf(x) === i)
|
||||
|
||||
// The add-ons the agent grants, as rows. A granted add-on this account cannot
|
||||
|
||||
+98
@@ -0,0 +1,98 @@
|
||||
// The options of the Tools list. A saved agent stores a capability twice: as a
|
||||
// switch of a built-in group (builtins_off, builtins_on) and as a list of
|
||||
// grants (builtins). The Tools list shows one switch per capability, and the
|
||||
// grants that refine it sit under it as options. Nothing here changes what is
|
||||
// stored. No React, so a node test drives it.
|
||||
|
||||
// The grant that is also an opt-in group. The switch is the group.
|
||||
export const SAVED_AGENTS_GROUP = 'saved_agents'
|
||||
|
||||
// The grants nested under the switch of a built-in group, in the order shown.
|
||||
export const GROUP_OPTIONS = {
|
||||
triggers: ['triggers.propose', 'triggers.run'],
|
||||
changes: ['memory.write', 'profile.write', 'skills.write', 'pages.write', 'dashboard.write'],
|
||||
files: ['files.upload', 'act.files'],
|
||||
}
|
||||
|
||||
// The grants that have no switch to hang from. They sit in a section of their
|
||||
// own, with a line that says what the section is.
|
||||
export const GRANT_SECTIONS = [
|
||||
{ key: 'messaging', icon: 'chat', names: ['talkback.channels', 'talkback.new_channel'] },
|
||||
{ key: 'unattended', icon: 'clock', names: ['act.addons', 'act.send', 'act.spend'] },
|
||||
]
|
||||
|
||||
// The grants a messaging connection also has to allow on its own permissions
|
||||
// page (the capabilities of a binding). The act.* grants are the agent's alone.
|
||||
export const BINDING_CAPS = new Set([
|
||||
'memory.write', 'profile.write', 'skills.write', 'pages.write', 'dashboard.write',
|
||||
'files.upload', 'triggers.propose', 'triggers.run', 'talkback.channels', 'talkback.new_channel',
|
||||
])
|
||||
|
||||
const list = (x) => (Array.isArray(x) ? x : [])
|
||||
|
||||
// The key of a grant in the locale files.
|
||||
export const grantKey = (name) => name.replace(/\./g, '_')
|
||||
|
||||
// Where each grant of a list goes: under a group switch (byGroup), in a
|
||||
// section (bySection), or nowhere known (other: a grant of a newer server, or
|
||||
// one this server no longer declares). saved_agents is the switch itself and
|
||||
// has no place. A grant whose group switch is not in `groups` goes to `other`,
|
||||
// so it is never hidden.
|
||||
export function placeGrants(grants, groups) {
|
||||
const byName = new Map(list(grants).map((g) => [g.name, g]))
|
||||
const present = new Set(list(groups))
|
||||
const used = new Set([SAVED_AGENTS_GROUP])
|
||||
const byGroup = {}
|
||||
for (const [group, names] of Object.entries(GROUP_OPTIONS)) {
|
||||
if (!present.has(group)) continue
|
||||
byGroup[group] = names.filter((n) => byName.has(n)).map((n) => byName.get(n))
|
||||
names.forEach((n) => used.add(n))
|
||||
}
|
||||
const bySection = {}
|
||||
for (const s of GRANT_SECTIONS) {
|
||||
bySection[s.key] = s.names.filter((n) => byName.has(n)).map((n) => byName.get(n))
|
||||
s.names.forEach((n) => used.add(n))
|
||||
}
|
||||
const other = list(grants).filter((g) => !used.has(g.name))
|
||||
// A grant whose group is not listed is not hidden.
|
||||
for (const [group, names] of Object.entries(GROUP_OPTIONS)) {
|
||||
if (present.has(group)) continue
|
||||
for (const n of names) if (byName.has(n)) other.push(byName.get(n))
|
||||
}
|
||||
return { byGroup, bySection, other }
|
||||
}
|
||||
|
||||
// The saved-agents switch is on when the group is on or the agent holds the
|
||||
// grant: the server turns the group on at save for an agent that holds it.
|
||||
export function savedAgentsOn(form) {
|
||||
return list(form.builtins_on).includes(SAVED_AGENTS_GROUP) || list(form.builtins).includes(SAVED_AGENTS_GROUP)
|
||||
}
|
||||
|
||||
// The messaging connections of an agent, as the Tools list names them: the
|
||||
// bindings whose agent is this one, with the capabilities each one allows, the
|
||||
// name of the kind and the page that edits them. kinds is the list the
|
||||
// connectors call returns ({ kind, addon, title }).
|
||||
export function agentConnections(bindings, kinds, agentId) {
|
||||
if (!agentId) return []
|
||||
const byKind = new Map(list(kinds).map((k) => [k.kind, k]))
|
||||
return list(bindings)
|
||||
.filter((b) => b.agent_id === agentId)
|
||||
.map((b) => {
|
||||
const k = byKind.get(b.kind)
|
||||
const title = k?.title || b.kind || ''
|
||||
return {
|
||||
id: b.id,
|
||||
name: [title, b.name].filter(Boolean).join(' '),
|
||||
caps: list(b.caps),
|
||||
// The page of the kind opens the binding and shows its permissions.
|
||||
to: k?.addon ? `/app/addons/${encodeURIComponent(k.addon)}/apps?binding=${encodeURIComponent(b.id)}` : '/app/chats/connectors',
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// The connections that do not allow a grant yet. Only for a grant the agent
|
||||
// holds and a connection has a permission for: nothing for the act.* grants.
|
||||
export function connectionsMissing(name, connections) {
|
||||
if (!BINDING_CAPS.has(name)) return []
|
||||
return list(connections).filter((c) => !c.caps.includes(name))
|
||||
}
|
||||
@@ -66,35 +66,90 @@ test('agentGrants lists every declared grant, on when the agent holds it, and ke
|
||||
assert.deepEqual(grantsAfter({}, ['memory.write'], true), ['memory.write'])
|
||||
})
|
||||
|
||||
test('the Tools list shows each grant with its plain words, marks the sensitive ones and offers no bulk change', async () => {
|
||||
const optionGrants = [
|
||||
{ name: 'memory.write', title: 'Remember things', description: 'x', sensitive: false },
|
||||
{ name: 'skills.write', title: 'Write skills', description: 'x', sensitive: true },
|
||||
{ name: 'triggers.propose', title: 'Propose triggers', description: 'x', sensitive: false },
|
||||
{ name: 'triggers.run', title: 'Run triggers', description: 'x', sensitive: false },
|
||||
{ name: 'files.upload', title: 'Receive files', description: 'x', sensitive: false },
|
||||
{ name: 'talkback.channels', title: 'Reply', description: 'x', sensitive: false },
|
||||
{ name: 'act.send', title: 'Send', description: 'x', sensitive: true },
|
||||
{ name: 'saved_agents', title: 'Call your saved agents', description: 'x', sensitive: false },
|
||||
{ name: 'from.the.future', title: 'Future', description: 'x', sensitive: false, gone: true },
|
||||
]
|
||||
|
||||
async function toolGroupsHarness() {
|
||||
const { hookHarness } = await import('./chatcommands-lifecycle.mjs')
|
||||
const imports = Object.assign({}, ...await Promise.all(['chatMCP', 'chatCommands', 'toolOptions'].map((n) => import(`../../src/utils/${n}.js`))))
|
||||
return hookHarness('../../src/hooks/useToolGroups.js', 'useToolGroups', {
|
||||
useTranslation: () => ({ t: (key, o) => (o?.defaultValue ?? key) }), ...imports,
|
||||
}, (source) => source.replace(/export const/g, 'const'))
|
||||
}
|
||||
|
||||
test('the Tools list nests each grant under the switch it refines, shows every grant once and offers no bulk change', async () => {
|
||||
const { agentGrants } = await import('../../src/utils/agentTools.js')
|
||||
const { switchRows, switchCounts } = await import('../../src/utils/chatSwitchRows.js')
|
||||
const imports = Object.assign({}, ...await Promise.all(['chatMCP', 'chatCommands'].map((n) => import(`../../src/utils/${n}.js`))))
|
||||
const harness = hookHarness('../../src/hooks/useToolGroups.js', 'useToolGroups', {
|
||||
useTranslation: () => ({ t: (key, o) => (o?.defaultValue ?? key) }), connectorRef: imports.connectorRef, unknownTextKey: imports.unknownTextKey,
|
||||
}, (source) => source.replace(/export const/g, 'const'))
|
||||
const harness = await toolGroupsHarness()
|
||||
const toggled = []
|
||||
const base = { builtins: [], addons: [], servers: [], connectors: [], commands: {}, setBuiltinsOn() {}, setAddonsOn() {}, setMCPOn() {} }
|
||||
const editable = { list: agentGrants(grantCatalog, ['memory.write']), editable: true, onToggle: (n, on) => toggled.push([n, on]) }
|
||||
const groups = harness.render({ ...base, grants: editable }, {})
|
||||
const g = groups.find((x) => x.key === 'grants')
|
||||
assert.ok(g, 'a grants group')
|
||||
assert.equal(g.onSet, undefined, 'no group setter: Select all never grants a right')
|
||||
assert.deepEqual(g.rows.map((r) => [r.label, r.description, r.on, !!r.warn, !!r.readOnly]), [
|
||||
['Remember things', 'The agent can propose a note in your memory.', true, false, false],
|
||||
['Write skills', 'The agent can propose a skill.', false, true, false],
|
||||
])
|
||||
assert.equal(g.rows[1].note, 'tools.grantSensitive')
|
||||
g.rows[1].onToggle(true)
|
||||
assert.deepEqual(toggled, [['skills.write', true]])
|
||||
const mk = (group, off) => ({ group, off, usable: true, tools: [] })
|
||||
const base = { builtins: [mk('triggers', false), mk('changes', true), mk('files', false), mk('saved_agents', false)], addons: [], servers: [], connectors: [], commands: {}, setBuiltinsOn() {}, setAddonsOn() {}, setMCPOn() {}, toggleBuiltin() {} }
|
||||
const grants = { list: agentGrants(optionGrants.slice(0, 8), ['memory.write', 'triggers.propose', 'act.send', 'from.the.future']), editable: true, onToggle: (n, on) => toggled.push([n, on]) }
|
||||
const groups = harness.render({ ...base, grants }, {})
|
||||
const row = (id) => groups.find((x) => x.key === 'builtins').rows.find((r) => r.id === id)
|
||||
assert.deepEqual(row('triggers').options.map((o) => [o.id, o.on, o.blocked]), [['triggers.propose', true, false], ['triggers.run', false, false]])
|
||||
assert.deepEqual(row('files').options.map((o) => o.id), ['files.upload'], 'only the grants the server declares')
|
||||
// The changes switch is off: its options are greyed, with the reason, and keep their stored state.
|
||||
assert.deepEqual(row('changes').options.map((o) => [o.id, o.on, o.blocked]), [['memory.write', true, true], ['skills.write', false, true]])
|
||||
assert.equal(row('changes').options[0].reason, 'tools.optionNeeds')
|
||||
assert.equal(row('saved_agents').options, undefined, 'saved agents is one switch')
|
||||
row('triggers').options[1].onToggle(true)
|
||||
assert.deepEqual(toggled, [['triggers.run', true]])
|
||||
// A grant with no switch to hang from is in a section; an unknown held one stays visible.
|
||||
assert.deepEqual(groups.find((x) => x.key === 'messaging').rows.map((r) => r.id), ['talkback.channels'])
|
||||
assert.deepEqual(groups.find((x) => x.key === 'unattended').rows.map((r) => [r.id, !!r.warn, r.on]), [['act.send', true, true]])
|
||||
assert.deepEqual(groups.find((x) => x.key === 'grants').rows.map((r) => r.id), ['from.the.future'])
|
||||
const all = groups.flatMap((g) => g.rows.flatMap((r) => [r.id, ...(r.options || []).map((o) => o.id)]))
|
||||
assert.equal(new Set(all.filter((x) => x.includes('.'))).size, all.filter((x) => x.includes('.')).length, 'no grant twice')
|
||||
// The count and the bulk rows leave the grants out.
|
||||
assert.deepEqual(switchCounts(switchRows(groups)), { on: 0, total: 0 })
|
||||
assert.deepEqual(groups.filter((g) => !g.onSet).map((g) => g.key), ['messaging', 'unattended', 'grants'])
|
||||
assert.deepEqual(switchCounts(switchRows(groups)), { on: 3, total: 4 })
|
||||
// A chat shows the held grants read only.
|
||||
const chat = harness.render({ ...base, grants: { list: agentGrants(grantCatalog, ['memory.write'], { heldOnly: true }), editable: false } }, {})
|
||||
assert.deepEqual(chat.find((x) => x.key === 'grants').rows.map((r) => [r.label, r.readOnly]), [['Remember things', true]])
|
||||
// No grants prop, no section content.
|
||||
assert.equal(harness.render(base, {}).find((x) => x.key === 'grants').rows.length, 0)
|
||||
const chat = harness.render({ ...base, grants: { list: agentGrants(optionGrants, ['memory.write'], { heldOnly: true }), editable: false } }, {})
|
||||
assert.deepEqual(chat.find((x) => x.key === 'builtins').rows.find((r) => r.id === 'changes').options.map((o) => [o.id, o.readOnly]), [['memory.write', true]])
|
||||
// No grants prop, no content.
|
||||
assert.equal(harness.render(base, {}).filter((x) => x.key === 'grants' || x.key === 'messaging').every((g) => g.rows.length === 0), true)
|
||||
})
|
||||
|
||||
test('a connection that does not allow a grant the agent holds is named under that option, with a link', async () => {
|
||||
const { agentGrants } = await import('../../src/utils/agentTools.js')
|
||||
const { agentConnections } = await import('../../src/utils/toolOptions.js')
|
||||
const harness = await toolGroupsHarness()
|
||||
const connections = agentConnections(
|
||||
[{ id: 'b1', name: 'Bender', kind: 'slack', agent_id: 'a1', caps: [] }, { id: 'b2', name: 'Other', kind: 'slack', agent_id: 'a2', caps: [] }, { id: 'b3', name: 'Ok', kind: 'telegram', agent_id: 'a1', caps: ['triggers.propose'] }],
|
||||
[{ kind: 'slack', addon: 'slack', title: 'Slack' }], 'a1')
|
||||
assert.deepEqual(connections.map((c) => [c.name, c.to]), [['Slack Bender', '/app/addons/slack/apps?binding=b1'], ['telegram Ok', '/app/chats/connectors']])
|
||||
const base = { builtins: [{ group: 'triggers', off: false, usable: true }], addons: [], servers: [], connectors: [], commands: {}, toggleBuiltin() {}, connections }
|
||||
const grants = { list: agentGrants(optionGrants, ['triggers.propose', 'act.send']), editable: true, onToggle() {} }
|
||||
const groups = harness.render({ ...base, grants }, {})
|
||||
const rows = groups.find((x) => x.key === 'builtins').rows[0].options
|
||||
assert.deepEqual(rows[0].notes.map((n) => [n.key, n.link.to]), [['b1', '/app/addons/slack/apps?binding=b1']])
|
||||
assert.deepEqual(rows[1].notes, [], 'an option that is off has no note')
|
||||
assert.deepEqual(groups.find((x) => x.key === 'unattended').rows[0].notes, [], 'the act grants are the agent\'s alone')
|
||||
// The agent not saved yet has no connections.
|
||||
assert.deepEqual(agentConnections([{ agent_id: '' }], [], ''), [])
|
||||
})
|
||||
|
||||
test('saved agents is one switch: either stored value turns it on, off clears both, on adds only the group', async () => {
|
||||
const { agentBuiltins, savedAgentsGrantAfter, builtinsAfter } = await import('../../src/utils/agentTools.js')
|
||||
const groups = [{ group: 'saved_agents', opt_in: true }]
|
||||
assert.equal(agentBuiltins(groups, { builtins_on: [], builtins: ['saved_agents'] })[0].off, false)
|
||||
assert.equal(agentBuiltins(groups, { builtins_on: ['saved_agents'], builtins: [] })[0].off, false)
|
||||
assert.equal(agentBuiltins(groups, { builtins_on: [], builtins: [] })[0].off, true)
|
||||
const held = { builtins_on: ['saved_agents'], builtins: ['saved_agents', 'memory.write'] }
|
||||
assert.deepEqual(savedAgentsGrantAfter(held, ['saved_agents'], false), ['memory.write'])
|
||||
assert.deepEqual(builtinsAfter(held, groups, ['saved_agents'], false).builtins_on, [])
|
||||
assert.deepEqual(savedAgentsGrantAfter({ builtins: [] }, ['saved_agents'], true), [], 'switching on never adds the first grant')
|
||||
assert.deepEqual(savedAgentsGrantAfter(held, ['web'], false), held.builtins)
|
||||
})
|
||||
|
||||
test('agent tools: an add-on with a credential shows the connections the agent names, and ones the person no longer has are left out', () => {
|
||||
|
||||
@@ -270,7 +270,7 @@ for (const provider of ['copper-runner', 'violet-executor']) test(`typed safety:
|
||||
// The rows of the Tools list come from useToolGroups, which the Tools menu
|
||||
// of a chat and the agent form both use.
|
||||
const toolGroups = hookHarness('../../src/hooks/useToolGroups.js', 'useToolGroups', {
|
||||
useTranslation:() => ({t:key => key}), connectorRef: imports.connectorRef, unknownTextKey: imports.unknownTextKey,
|
||||
useTranslation:() => ({t:key => key}), connectorRef: imports.connectorRef, unknownTextKey: imports.unknownTextKey, ...await import('../../src/utils/toolOptions.js'),
|
||||
}, source => source.replace(/export const/g, 'const'))
|
||||
const group = {group:'shell',providers:{bash:provider},provider,usable:true}
|
||||
const render = (actor = 'alice:1', override) => {
|
||||
|
||||
@@ -279,9 +279,19 @@ group on). A sensitive grant changes what the agent may do or reach later; the
|
||||
editor marks it. The five `*.write` grants let the agent propose a memory note,
|
||||
its profile, a skill, a page or a dashboard change with `propose_change`; you
|
||||
confirm every proposal, and you can undo it. The **Tools** list of the agent form
|
||||
and of a chat show the grants in one group, "What the agent may change": the form has a
|
||||
switch per grant, each with its description and a mark on the sensitive ones; a chat of
|
||||
the agent lists the grants it holds, read only. "Select all" never touches this group. A write to the agent without the
|
||||
and of a chat show each grant once, as an option under the switch it refines:
|
||||
"Create and manage triggers" holds "Also propose from messaging apps" (`triggers.propose`)
|
||||
and "Let triggers start from messaging apps" (`triggers.run`); "Memory and profile
|
||||
changes" holds the five `*.write` grants; "Your files" holds `files.upload` and
|
||||
`act.files`. An option is greyed, with the reason, while its switch is off, and keeps its
|
||||
stored value. `talkback.channels` and `talkback.new_channel` are in the section
|
||||
"Messaging apps", and `act.addons`, `act.send` and `act.spend` in "When nobody is
|
||||
watching". "Saved agents" is one switch: either the group `saved_agents` in
|
||||
`builtins_on` or the grant of that name turns it on, switching it off removes both, and
|
||||
switching it on adds only the group. Each switch and option has one line that says what it
|
||||
lets the model do, and the form names a messaging connection of the agent that does not
|
||||
allow an option the agent holds, with a link to the permissions of that connection. A chat
|
||||
of the agent lists the grants it holds, read only. "Select all" never touches a grant. A write to the agent without the
|
||||
`builtins` field keeps them, an empty list clears them and an unknown name is
|
||||
refused (an import drops it).
|
||||
|
||||
@@ -639,7 +649,10 @@ and a `trigger_proposed` event announces it to a client that is watching.
|
||||
A change does not count towards the 50 triggers or the 10 waiting proposals. At
|
||||
most 10 changes wait at a time. Like the other trigger tools, these tools are
|
||||
offered only in a chat a person started: a trigger run, a connector run and a
|
||||
sub-agent never get them.
|
||||
sub-agent never get them. A chat that a messaging app started gets `propose_trigger`
|
||||
and `list_triggers` when the connection holds `triggers.propose` and the agent holds
|
||||
the grant "Also propose from messaging apps"; `update_trigger` and `delete_trigger` stay in
|
||||
the app.
|
||||
|
||||
### Clusters
|
||||
|
||||
|
||||
Reference in new issue
Block a user