Preparing your environment ...

NetSuite Connection Required

{{ authError }}

{{ welcomeGreeting }}

{{ welcomeDateLine }} · Here's your business at a glance.

{{ config.labels?.settings || 'Settings' }}

Model

Choose the AI model for processing requests

Provider: {{ aiProvider.name || aiProvider.type || 'Not configured' }}

Current Model: {{ aiProvider.model || 'Not selected' }}

Dashboard

How many pinned portlets can live on the dashboard at once.

Demo Mode

Fills the dashboard with polished sample portlets and matching conversations. Your real pins are hidden (not deleted) while it is on, and sample cards never contact NetSuite, so they can never show a connection or session error. Turn off to restore your own dashboard.

{{ userSettings.demoMode ? 'On — dashboard is showing sample data' : 'Off' }}

Company Branding

Sets the logo, name, and colours used across the app and in exported letterhead reports.

PNG, JPG, WEBP or SVG · max 3MB

Colours auto-fill from the logo on upload; Smart match refines them with AI.

{{ brandingForm.companyName || 'Company Name' }}
13 July 2026
Sample Report Title
Highlight
{{ brandingForm.error }} {{ brandingForm.success }}

Integrations

Operator diagnostic

This page exists to diagnose broken wiring, not to set anything up. It is not part of the customer product: a connector's configuration and its usage live on that source's page under Data Sources, which is also where a tool can be called to prove it works.

External tools

Tools the agent can call, from config/external-tools.json. A tool is offered to the agent when it is enabled and any credential it requires is present - some providers need no key at all. Keys stay on the server and are never sent to this page.

No external tools configured.

{{ tool.name }} {{ tool.registeredForAgent ? 'Live for agent' : (tool.enabled ? 'Enabled, no key' : 'Disabled') }} {{ !tool.requiresKey ? 'No key needed' : (tool.hasKey ? 'Key set' : 'No key') }}

{{ tool.description }}

{{ tool.method }} {{ tool.baseUrl }} · auth: {{ tool.authHeader }} header · auth: query param · inputs in {{ tool.sendAs }}

inputs: {{ fi ? ', ' : '' }}{{ f.field }}*:{{ f.type }}

Profile

{{ netsuiteAuth.currentUser && netsuiteAuth.currentUser.firstName ? netsuiteAuth.currentUser.firstName.charAt(0) : 'U' }}
{{ netsuiteAuth.currentUser ? netsuiteAuth.currentUser.firstName : 'User' }}
{{ config.companyName }}

Data Sources

Connect the systems TaskDrive AI reads from. NetSuite is your live source today. We build the rest on request, so tell us which one matters to you.

Oracle NetSuite
Account {{ netsuiteAuth.accountId || '—' }} · {{ netsuiteAuth.currentUser.firstName }} · Bundle role: TaskDrive AI
{{ netsuiteConnectionLabel }}
{{ netsuiteAuth.mcpError }}

Xero, Microsoft Dynamics 365 and Workday connectors are in development.

No integrations match your search.

Parcel tracking

Carrier tracking numbers you asked us to watch, their last known status, and what changed since you last looked.

Connector {{ shipmentToolDef.registeredForAgent ? 'Live for the agent' : (shipmentToolDef.enabled ? 'Enabled, no key' : 'Disabled') }} {{ !shipmentToolDef.requiresKey ? 'No key needed' : (shipmentToolDef.hasKey ? 'Key set' : 'No key') }}

Configured on the server. Keys stay there and never reach this page.

The watchlist appears here once carrier lookups are switched on. Adding a tracking number that could never be checked would be a control that cannot do its job, so it is not offered yet.

Shipment tracking

{{ shipmentDelayedCount }} delayed {{ shipmentUnseen.total }} new {{ shipmentBudget.remaining }} of {{ shipmentBudget.limit }} checks left today
Live carrier lookups are unavailable
{{ shipmentAvailable.message }} You can still add numbers now; they will be checked once it is switched on.
{{ shipmentUnseen.total }} shipment update{{ shipmentUnseen.total === 1 ? '' : 's' }}
  • {{ a.severity === 'delay' ? 'Delayed' : 'Update' }} {{ a.message }}
No shipments are being tracked. Add a carrier tracking number below and its status will be kept here.
{{ s.label || s.trackingNumber }} {{ s.trackingNumber }} new {{ shipmentStatusLabel(s) }}
{{ s.delaySummary }} Last check failed: {{ s.lastError }} {{ s.status.lastEventStatus || s.status.statusText }} Not checked yet. · checked {{ shipmentAgo(s.lastCheckedAt) }}
{{ shipments.length }} of {{ shipmentLimits.maxWatches }} tracked

Weather & location

Resolve a place, then read its current conditions, forecast or history - so a question about demand can be asked against the weather that came with it.

What is switched on

No weather or location tools are configured on this instance.
{{ t.name }} {{ t.registeredForAgent ? 'Live for the agent' : (t.enabled ? 'Enabled, no key' : 'Disabled') }} {{ !t.requiresKey ? 'No key needed' : (t.hasKey ? 'Key set' : 'No key') }} {{ t.description }}

Configured on the server. Open-Meteo needs no credential at all, so a tool here showing "no key needed" is not missing anything.

This browser's location

Shared with this page

Optional. Your browser asks you first, and nothing is read until you allow it. The coordinate is rounded to about 110 m the moment it arrives, is held only while this page is open, and is used for one thing: filling the latitude and longitude of a weather lookup. It is never added to a prompt, never saved, and never written to a log.

{{ geoDisplay }} fix accurate to about {{ geo.accuracyM }} m
{{ geo.error }}

"Forget it" clears the coordinate from this page. The permission itself is your browser's - withdraw it from the padlock or site-settings menu next to the address bar, and this page will notice.

Your browser is currently blocking location for this site, so "Ask again" cannot re-open the prompt. Allow it from the padlock or site-settings menu next to the address bar first. Everything else on this page works without it.

Using it

Ask in a conversation and name the place - "was it raining in Chippendale the week our Sydney orders dropped?". The agent resolves the place to coordinates itself and reads the weather from there; you never have to type a coordinate, and the answer comes back with the rest of the analysis rather than on its own.

Run a lookup

Operator

Calls the live provider once with the values below. Available only to a local-development operator session, because a lookup is spend that lands on us.

{{ t.name }}
{{ externalToolResults[t.name].ok ? 'Success' : 'Failed' }} HTTP {{ externalToolResults[t.name].httpStatus }} {{ externalToolResults[t.name].durationMs }}ms

{{ externalToolResults[t.name].message }}

{{ formatToolResult(externalToolResults[t.name].data || externalToolResults[t.name].body) }}

Weather and location data by Open-Meteo.com, used under CC BY 4.0.

Briefs

The business context TaskDrive AI uses to interpret every question. Edit any layer to sharpen your answers.

{{ driftError.message }}
Loading briefs…

{{ b.title }}

{{ b.description }}

{{ b.scope === 'user' ? 'Me' : 'Org' }}

Shared context, read only ({{ b.readOnlyReason }})

Profile drift detected

Your team asked about "{{ drift.term }}" {{ drift.count }} times in the last {{ drift.windowDays }} days, but it isn't in any brief yet. Adding it keeps answers consistent for this recurring topic.

Adding this to a shared layer needs shared-context permission, so there is nothing to act on here.

{{ b.content }}

No context added yet.

{{ b.updatedAt ? 'Updated ' + formatTime(b.updatedAt) : 'Not set' }} by {{ b.updatedBy }}

{{ config.labels?.conversations || 'Conversations' }}

Recent

{{ conversations.length ? 'No conversations match your search.' : 'No conversations yet' }}
{{ conv.title }}
{{ formatConvDate(conv.updatedAt) }}
No archived conversations.
{{ conv.title }}
Messages removed from this conversation. The title, dates and usage history are kept. Prompt-audit files created before this update may retain prompt text until an administrator removes them or log rotation deletes them.
{{ formatConvDate(conv.archivedAt) }}

{{ isEditMode ? 'Edit Item' : (showAddForm ? 'Add Entry' : (config.labels?.promptLibrary || 'Automated Reports')) }}

Access level: {{ (config.accessLevels.find(l => l.id === config.accessLevel) || {}).label || config.accessLevel }}
Agent performance How the running agents are doing - triaged, accepted, handling time, time saved.
{{ promptTabs.find(t => t.k === promptTab).count === 0 ? 'No prompts in ' + promptTabs.find(t => t.k === promptTab).label + ' yet.' : 'No prompts match this category.' }}
{{ item.category || item.groupLabel }} {{ item.tier }} {{ item.access }}
{{ item.label }}
{{ item.description }}
{{ item.type === 'search' ? 'Saved Search' : 'Report' }} · {{ item.nsId }}
{{ promptLibrarySuccessMessage }}
No groups exist — add a group first.
{{ promptLibraryFormErrors.groupId }}
{{ promptLibraryForm.tier || 'user' }}
{{ promptLibraryFormErrors.label }}
{{ promptLibraryFormErrors.prompt }}
{{ noticeTitle }}
{{ noticeMessage }}
Something went wrong
{{ errorMessage }}
Done
{{ successMessage }}
Still loading. If this persists, reload the page.