@open-mercato/core 0.6.1-develop.3287.1.450f4ffb56 → 0.6.1-develop.3306.1.9ad9ff2526
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.turbo/turbo-build.log +1 -1
- package/AGENTS.md +14 -0
- package/dist/modules/auth/backend/roles/[id]/edit/page.js +2 -1
- package/dist/modules/auth/backend/roles/[id]/edit/page.js.map +2 -2
- package/dist/modules/auth/backend/users/[id]/edit/page.js +2 -5
- package/dist/modules/auth/backend/users/[id]/edit/page.js.map +2 -2
- package/dist/modules/catalog/ai-agents.js +47 -5
- package/dist/modules/catalog/ai-agents.js.map +2 -2
- package/dist/modules/catalog/backend/catalog/categories/[id]/edit/page.js +2 -5
- package/dist/modules/catalog/backend/catalog/categories/[id]/edit/page.js.map +2 -2
- package/dist/modules/catalog/backend/catalog/products/MerchandisingAssistantSheet.js +4 -3
- package/dist/modules/catalog/backend/catalog/products/MerchandisingAssistantSheet.js.map +2 -2
- package/dist/modules/catalog/backend/catalog/products/[id]/page.js +2 -9
- package/dist/modules/catalog/backend/catalog/products/[id]/page.js.map +2 -2
- package/dist/modules/catalog/backend/catalog/products/[productId]/variants/[variantId]/page.js +2 -9
- package/dist/modules/catalog/backend/catalog/products/[productId]/variants/[variantId]/page.js.map +2 -2
- package/dist/modules/customers/ai-agents.js +174 -1
- package/dist/modules/customers/ai-agents.js.map +2 -2
- package/dist/modules/customers/ai-tools/deal-analyzer-pack.js +196 -0
- package/dist/modules/customers/ai-tools/deal-analyzer-pack.js.map +7 -0
- package/dist/modules/customers/ai-tools.js +3 -1
- package/dist/modules/customers/ai-tools.js.map +2 -2
- package/dist/modules/customers/backend/customers/companies/page.js +11 -1
- package/dist/modules/customers/backend/customers/companies/page.js.map +2 -2
- package/dist/modules/customers/backend/customers/deals/page.js +11 -1
- package/dist/modules/customers/backend/customers/deals/page.js.map +2 -2
- package/dist/modules/customers/backend/customers/people/page.js +11 -1
- package/dist/modules/customers/backend/customers/people/page.js.map +2 -2
- package/dist/modules/customers/commands/companies.js +37 -15
- package/dist/modules/customers/commands/companies.js.map +2 -2
- package/dist/modules/customers/components/detail/AiActionChips.js +2 -2
- package/dist/modules/customers/components/detail/AiActionChips.js.map +2 -2
- package/dist/modules/customers/components/detail/ChangelogTab.js +3 -9
- package/dist/modules/customers/components/detail/ChangelogTab.js.map +2 -2
- package/dist/modules/customers/components/detail/changelogValues.js +35 -0
- package/dist/modules/customers/components/detail/changelogValues.js.map +7 -0
- package/dist/modules/customers/components/detail/customFieldUtils.js +1 -1
- package/dist/modules/customers/components/detail/customFieldUtils.js.map +1 -1
- package/dist/modules/customers/components/formConfig.js +3 -2
- package/dist/modules/customers/components/formConfig.js.map +2 -2
- package/dist/modules/customers/widgets/injection/ai-assistant-trigger/widget.client.js +4 -9
- package/dist/modules/customers/widgets/injection/ai-assistant-trigger/widget.client.js.map +2 -2
- package/dist/modules/customers/widgets/injection/ai-deal-analyzer-trigger/widget.client.js +302 -0
- package/dist/modules/customers/widgets/injection/ai-deal-analyzer-trigger/widget.client.js.map +7 -0
- package/dist/modules/customers/widgets/injection/ai-deal-analyzer-trigger/widget.js +17 -0
- package/dist/modules/customers/widgets/injection/ai-deal-analyzer-trigger/widget.js.map +7 -0
- package/dist/modules/customers/widgets/injection/ai-deal-detail-trigger/widget.client.js +2 -2
- package/dist/modules/customers/widgets/injection/ai-deal-detail-trigger/widget.client.js.map +2 -2
- package/dist/modules/customers/widgets/injection-table.js +2 -2
- package/dist/modules/customers/widgets/injection-table.js.map +2 -2
- package/dist/modules/directory/backend/directory/organizations/[id]/edit/page.js +2 -5
- package/dist/modules/directory/backend/directory/organizations/[id]/edit/page.js.map +2 -2
- package/dist/modules/directory/backend/directory/tenants/[id]/edit/page.js +2 -5
- package/dist/modules/directory/backend/directory/tenants/[id]/edit/page.js.map +2 -2
- package/dist/modules/resources/backend/resources/resources/[id]/page.js +2 -5
- package/dist/modules/resources/backend/resources/resources/[id]/page.js.map +2 -2
- package/dist/modules/sales/backend/sales/channels/[channelId]/edit/page.js +2 -25
- package/dist/modules/sales/backend/sales/channels/[channelId]/edit/page.js.map +2 -2
- package/dist/modules/sales/components/channels/ChannelOfferForm.js +2 -43
- package/dist/modules/sales/components/channels/ChannelOfferForm.js.map +2 -2
- package/dist/modules/sales/components/documents/LineItemDialog.js +162 -42
- package/dist/modules/sales/components/documents/LineItemDialog.js.map +2 -2
- package/dist/modules/sales/components/documents/customFieldHelpers.js +4 -31
- package/dist/modules/sales/components/documents/customFieldHelpers.js.map +2 -2
- package/package.json +15 -6
- package/src/modules/auth/backend/roles/[id]/edit/page.tsx +2 -1
- package/src/modules/auth/backend/users/[id]/edit/page.tsx +2 -5
- package/src/modules/business_rules/migrations/.snapshot-open-mercato.json +746 -394
- package/src/modules/catalog/ai-agents.ts +62 -4
- package/src/modules/catalog/backend/catalog/categories/[id]/edit/page.tsx +2 -5
- package/src/modules/catalog/backend/catalog/products/MerchandisingAssistantSheet.tsx +4 -3
- package/src/modules/catalog/backend/catalog/products/[id]/page.tsx +2 -12
- package/src/modules/catalog/backend/catalog/products/[productId]/variants/[variantId]/page.tsx +2 -10
- package/src/modules/catalog/migrations/.snapshot-open-mercato.json +2519 -1307
- package/src/modules/customer_accounts/migrations/.snapshot-open-mercato.json +828 -834
- package/src/modules/customers/AGENTS.md +6 -1
- package/src/modules/customers/ai-agents.ts +213 -6
- package/src/modules/customers/ai-tools/deal-analyzer-pack.ts +286 -0
- package/src/modules/customers/ai-tools.ts +2 -0
- package/src/modules/customers/backend/customers/companies/page.tsx +10 -0
- package/src/modules/customers/backend/customers/deals/page.tsx +10 -0
- package/src/modules/customers/backend/customers/people/page.tsx +10 -0
- package/src/modules/customers/commands/companies.ts +38 -14
- package/src/modules/customers/components/detail/AiActionChips.tsx +2 -2
- package/src/modules/customers/components/detail/ChangelogTab.tsx +3 -10
- package/src/modules/customers/components/detail/changelogValues.ts +42 -0
- package/src/modules/customers/components/detail/customFieldUtils.ts +1 -1
- package/src/modules/customers/components/formConfig.tsx +3 -2
- package/src/modules/customers/i18n/de.json +7 -0
- package/src/modules/customers/i18n/en.json +7 -0
- package/src/modules/customers/i18n/es.json +7 -0
- package/src/modules/customers/i18n/pl.json +7 -0
- package/src/modules/customers/migrations/.snapshot-open-mercato.json +2313 -2336
- package/src/modules/customers/widgets/injection/ai-assistant-trigger/widget.client.tsx +4 -6
- package/src/modules/customers/widgets/injection/ai-deal-analyzer-trigger/widget.client.tsx +358 -0
- package/src/modules/customers/widgets/injection/ai-deal-analyzer-trigger/widget.ts +34 -0
- package/src/modules/customers/widgets/injection/ai-deal-detail-trigger/widget.client.tsx +2 -2
- package/src/modules/customers/widgets/injection-table.ts +12 -9
- package/src/modules/data_sync/migrations/.snapshot-open-mercato.json +554 -210
- package/src/modules/dictionaries/migrations/.snapshot-open-mercato.json +146 -146
- package/src/modules/directory/backend/directory/organizations/[id]/edit/page.tsx +2 -5
- package/src/modules/directory/backend/directory/tenants/[id]/edit/page.tsx +2 -5
- package/src/modules/directory/migrations/.snapshot-open-mercato.json +273 -140
- package/src/modules/feature_toggles/migrations/.snapshot-open-mercato.json +242 -137
- package/src/modules/integrations/migrations/.snapshot-open-mercato.json +498 -195
- package/src/modules/payment_gateways/migrations/.snapshot-open-mercato.json +158 -157
- package/src/modules/perspectives/migrations/.snapshot-open-mercato.json +274 -129
- package/src/modules/planner/migrations/.snapshot-open-mercato.json +327 -157
- package/src/modules/progress/AGENTS.md +72 -0
- package/src/modules/resources/backend/resources/resources/[id]/page.tsx +2 -5
- package/src/modules/resources/migrations/.snapshot-open-mercato.json +920 -470
- package/src/modules/sales/backend/sales/channels/[channelId]/edit/page.tsx +2 -27
- package/src/modules/sales/components/channels/ChannelOfferForm.tsx +2 -49
- package/src/modules/sales/components/documents/LineItemDialog.tsx +214 -78
- package/src/modules/sales/components/documents/customFieldHelpers.ts +4 -43
- package/src/modules/sales/i18n/de.json +3 -0
- package/src/modules/sales/i18n/en.json +3 -0
- package/src/modules/sales/i18n/es.json +3 -0
- package/src/modules/sales/i18n/pl.json +3 -0
- package/src/modules/sales/migrations/.snapshot-open-mercato.json +4740 -4778
- package/src/modules/shipping_carriers/migrations/.snapshot-open-mercato.json +340 -81
- package/src/modules/staff/migrations/.snapshot-open-mercato.json +1439 -729
|
@@ -158,6 +158,10 @@ const PROMPT_SECTIONS: PromptSection[] = [
|
|
|
158
158
|
'proactively offer the stats card at the start of an exploration',
|
|
159
159
|
'("Want me to show a quick catalog overview?") — most operators',
|
|
160
160
|
'find it useful before drilling in.',
|
|
161
|
+
'',
|
|
162
|
+
'If the operator asks what they can ask you, requests example questions,',
|
|
163
|
+
'or asks how you can help, answer directly from these instructions.',
|
|
164
|
+
'Do not call tools for capability / example-question prompts.',
|
|
161
165
|
].join('\n'),
|
|
162
166
|
},
|
|
163
167
|
{
|
|
@@ -244,6 +248,60 @@ function compilePromptTemplate(template: PromptTemplate): string {
|
|
|
244
248
|
.join('\n\n')
|
|
245
249
|
}
|
|
246
250
|
|
|
251
|
+
function textFromMessageContent(content: unknown): string {
|
|
252
|
+
if (typeof content === 'string') return content
|
|
253
|
+
if (!Array.isArray(content)) return ''
|
|
254
|
+
return content
|
|
255
|
+
.map((part) => {
|
|
256
|
+
if (typeof part === 'string') return part
|
|
257
|
+
if (!part || typeof part !== 'object') return ''
|
|
258
|
+
const record = part as Record<string, unknown>
|
|
259
|
+
return typeof record.text === 'string' ? record.text : ''
|
|
260
|
+
})
|
|
261
|
+
.join(' ')
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
function latestUserTextFromPrepareStepState(state: unknown): string {
|
|
265
|
+
const messages = (state as { messages?: unknown })?.messages
|
|
266
|
+
if (!Array.isArray(messages)) return ''
|
|
267
|
+
for (let index = messages.length - 1; index >= 0; index -= 1) {
|
|
268
|
+
const message = messages[index]
|
|
269
|
+
if (!message || typeof message !== 'object') continue
|
|
270
|
+
const record = message as Record<string, unknown>
|
|
271
|
+
if (record.role !== 'user') continue
|
|
272
|
+
return textFromMessageContent(record.content)
|
|
273
|
+
}
|
|
274
|
+
return ''
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
function isCatalogMetaHelpPrompt(text: string): boolean {
|
|
278
|
+
const normalized = text.toLowerCase()
|
|
279
|
+
if (!normalized.trim()) return false
|
|
280
|
+
const asksForQuestionIdeas =
|
|
281
|
+
(normalized.includes('question') || normalized.includes('questions')) &&
|
|
282
|
+
(normalized.includes('could ask') ||
|
|
283
|
+
normalized.includes('can ask') ||
|
|
284
|
+
normalized.includes('ask you') ||
|
|
285
|
+
normalized.includes('suggest') ||
|
|
286
|
+
normalized.includes('examples'))
|
|
287
|
+
const asksForCapabilities =
|
|
288
|
+
normalized.includes('what can you do') ||
|
|
289
|
+
normalized.includes('how can you help') ||
|
|
290
|
+
normalized.includes('what should i ask') ||
|
|
291
|
+
normalized.includes('what can i ask')
|
|
292
|
+
return asksForQuestionIdeas || asksForCapabilities
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
function buildCatalogAssistantPrepareStep() {
|
|
296
|
+
return async function catalogAssistantPrepareStep(state: unknown) {
|
|
297
|
+
const latestUserText = latestUserTextFromPrepareStepState(state)
|
|
298
|
+
if (isCatalogMetaHelpPrompt(latestUserText)) {
|
|
299
|
+
return { activeTools: [] }
|
|
300
|
+
}
|
|
301
|
+
return undefined
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
|
|
247
305
|
async function resolvePageContext(
|
|
248
306
|
input: AiAgentPageContextInput,
|
|
249
307
|
): Promise<string | null> {
|
|
@@ -269,8 +327,10 @@ const agent: AiAgentDefinition = {
|
|
|
269
327
|
requiredFeatures: [...REQUIRED_FEATURES],
|
|
270
328
|
readOnly: true,
|
|
271
329
|
mutationPolicy: 'read-only',
|
|
272
|
-
|
|
273
|
-
|
|
330
|
+
loop: {
|
|
331
|
+
maxSteps: 4,
|
|
332
|
+
prepareStep: buildCatalogAssistantPrepareStep() as NonNullable<AiAgentDefinition['loop']>['prepareStep'],
|
|
333
|
+
},
|
|
274
334
|
keywords: ['catalog', 'products', 'categories', 'variants', 'prices', 'offers', 'media'],
|
|
275
335
|
domain: 'catalog',
|
|
276
336
|
dataCapabilities: {
|
|
@@ -463,8 +523,6 @@ const merchandisingAgent: AiAgentDefinition = {
|
|
|
463
523
|
// the operator via the pending-action approval card. Per-tenant override
|
|
464
524
|
// can downgrade to `read-only` to lock writes without a redeploy.
|
|
465
525
|
mutationPolicy: 'confirm-required',
|
|
466
|
-
defaultProvider: 'openai',
|
|
467
|
-
defaultModel: 'gpt-5-mini',
|
|
468
526
|
keywords: ['catalog', 'merchandising', 'products', 'attributes', 'pricing', 'copy'],
|
|
469
527
|
domain: 'catalog',
|
|
470
528
|
dataCapabilities: {
|
|
@@ -8,6 +8,7 @@ import { updateCrud, deleteCrud } from '@open-mercato/ui/backend/utils/crud'
|
|
|
8
8
|
import { createCrudFormError } from '@open-mercato/ui/backend/utils/serverErrors'
|
|
9
9
|
import { collectCustomFieldValues } from '@open-mercato/ui/backend/utils/customFieldValues'
|
|
10
10
|
import { useT } from '@open-mercato/shared/lib/i18n/context'
|
|
11
|
+
import { extractCustomFieldEntries } from '@open-mercato/shared/lib/crud/custom-fields-client'
|
|
11
12
|
import { E } from '#generated/entities.ids.generated'
|
|
12
13
|
import { CategorySelect } from '../../../../../components/categories/CategorySelect'
|
|
13
14
|
import { CategorySlugFieldSync } from '../../../../../components/categories/CategorySlugFieldSync'
|
|
@@ -95,11 +96,7 @@ export default function EditCatalogCategoryPage({ params }: { params?: { id?: st
|
|
|
95
96
|
const record = Array.isArray(result?.items) ? result.items?.[0] : null
|
|
96
97
|
if (!record) throw new Error(t('catalog.categories.form.errors.notFound', 'Category not found'))
|
|
97
98
|
if (cancelled) return
|
|
98
|
-
const customValues
|
|
99
|
-
for (const [key, value] of Object.entries(record as Record<string, unknown>)) {
|
|
100
|
-
if (key.startsWith('cf_')) customValues[key] = value
|
|
101
|
-
else if (key.startsWith('cf:')) customValues[`cf_${key.slice(3)}`] = value
|
|
102
|
-
}
|
|
99
|
+
const customValues = extractCustomFieldEntries(record as Record<string, unknown>)
|
|
103
100
|
setInitialValues({
|
|
104
101
|
id: record.id,
|
|
105
102
|
name: record.name,
|
|
@@ -31,8 +31,9 @@
|
|
|
31
31
|
*/
|
|
32
32
|
|
|
33
33
|
import * as React from 'react'
|
|
34
|
-
import { Boxes, ChevronDown, FileText, Package, PanelRightOpen, PenLine,
|
|
34
|
+
import { Boxes, ChevronDown, FileText, Package, PanelRightOpen, PenLine, Tags, TrendingUp } from 'lucide-react'
|
|
35
35
|
import { AiChat, type AiChatSuggestion, type AiChatContextItem } from '@open-mercato/ui/ai/AiChat'
|
|
36
|
+
import { AiIcon } from '@open-mercato/ui/ai/AiIcon'
|
|
36
37
|
import { useAiDock } from '@open-mercato/ui/ai/AiDock'
|
|
37
38
|
import { useAiChatSessions } from '@open-mercato/ui/ai/AiChatSessions'
|
|
38
39
|
import { ChatPaneTabs } from '@open-mercato/ui/ai/ChatPaneTabs'
|
|
@@ -249,7 +250,7 @@ function useMerchandisingAgents(): MerchandisingAgentsState {
|
|
|
249
250
|
'catalog.merchandising_assistant.agents.merchandising.description',
|
|
250
251
|
'Draft copy, normalize attributes, and propose price changes for the current selection.',
|
|
251
252
|
),
|
|
252
|
-
icon: <
|
|
253
|
+
icon: <AiIcon className="size-4" />,
|
|
253
254
|
},
|
|
254
255
|
],
|
|
255
256
|
[t],
|
|
@@ -399,7 +400,7 @@ export function MerchandisingAssistantSheet({
|
|
|
399
400
|
agents.length > 1 && 'rounded-r-none border-r-0',
|
|
400
401
|
)}
|
|
401
402
|
>
|
|
402
|
-
<
|
|
403
|
+
<AiIcon className="size-4" />
|
|
403
404
|
<span>{labelText}</span>
|
|
404
405
|
{hasSelection ? (
|
|
405
406
|
<span
|
|
@@ -32,6 +32,7 @@ import { TagsInput } from "@open-mercato/ui/backend/inputs/TagsInput";
|
|
|
32
32
|
import { Textarea } from "@open-mercato/ui/primitives/textarea";
|
|
33
33
|
import { DataLoader } from "@open-mercato/ui/primitives/DataLoader";
|
|
34
34
|
import { cn } from "@open-mercato/shared/lib/utils";
|
|
35
|
+
import { extractCustomFieldEntries } from "@open-mercato/shared/lib/crud/custom-fields-client";
|
|
35
36
|
import { Spinner } from "@open-mercato/ui/primitives/spinner";
|
|
36
37
|
import {
|
|
37
38
|
apiCall,
|
|
@@ -619,7 +620,7 @@ export default function EditCatalogProductPage({
|
|
|
619
620
|
? readProductConversionRows(conversionsRes.result?.items)
|
|
620
621
|
: [];
|
|
621
622
|
initialConversionsRef.current = conversionRows;
|
|
622
|
-
const
|
|
623
|
+
const customValues = extractCustomFieldEntries(record);
|
|
623
624
|
const offers = readOfferSnapshots(record);
|
|
624
625
|
offerSnapshotsRef.current = offers;
|
|
625
626
|
const channelIds = extractChannelIds(offers);
|
|
@@ -2629,17 +2630,6 @@ function readOptionSchema(metadata: Record<string, any>): ProductOptionInput[] {
|
|
|
2629
2630
|
.filter((entry): entry is ProductOptionInput => !!entry);
|
|
2630
2631
|
}
|
|
2631
2632
|
|
|
2632
|
-
function extractCustomFields(record: Record<string, unknown>): {
|
|
2633
|
-
customValues: Record<string, unknown>;
|
|
2634
|
-
} {
|
|
2635
|
-
const customValues: Record<string, unknown> = {};
|
|
2636
|
-
Object.entries(record).forEach(([key, value]) => {
|
|
2637
|
-
if (key.startsWith("cf_")) customValues[key] = value;
|
|
2638
|
-
else if (key.startsWith("cf:")) customValues[`cf_${key.slice(3)}`] = value;
|
|
2639
|
-
});
|
|
2640
|
-
return { customValues };
|
|
2641
|
-
}
|
|
2642
|
-
|
|
2643
2633
|
function normalizeIdList(value: unknown): string[] {
|
|
2644
2634
|
const ids = Array.isArray(value)
|
|
2645
2635
|
? value
|
package/src/modules/catalog/backend/catalog/products/[productId]/variants/[variantId]/page.tsx
CHANGED
|
@@ -10,6 +10,7 @@ import { collectCustomFieldValues } from '@open-mercato/ui/backend/utils/customF
|
|
|
10
10
|
import { apiCall, readApiResultOrThrow } from '@open-mercato/ui/backend/utils/apiCall'
|
|
11
11
|
import { flash } from '@open-mercato/ui/backend/FlashMessages'
|
|
12
12
|
import { useT } from '@open-mercato/shared/lib/i18n/context'
|
|
13
|
+
import { extractCustomFieldEntries } from '@open-mercato/shared/lib/crud/custom-fields-client'
|
|
13
14
|
import { E } from '#generated/entities.ids.generated'
|
|
14
15
|
import { SendObjectMessageDialog } from '@open-mercato/ui/backend/messages'
|
|
15
16
|
import {
|
|
@@ -182,7 +183,7 @@ export default function EditVariantPage({ params }: { params?: { productId?: str
|
|
|
182
183
|
if (draft.priceId) priceIdMap[kindId] = draft.priceId
|
|
183
184
|
})
|
|
184
185
|
setExistingPriceIds(priceIdMap)
|
|
185
|
-
const customDefaults =
|
|
186
|
+
const customDefaults = extractCustomFieldEntries(record)
|
|
186
187
|
let loadedOptionDefinitions: OptionDefinition[] = []
|
|
187
188
|
if (resolvedProductId) {
|
|
188
189
|
const productRes = await apiCall<ProductResponse>(
|
|
@@ -631,15 +632,6 @@ async function loadVariantPrices(variantId: string, priceKinds: PriceKindSummary
|
|
|
631
632
|
return drafts
|
|
632
633
|
}
|
|
633
634
|
|
|
634
|
-
function extractCustomFieldValues(record: Record<string, unknown>): Record<string, unknown> {
|
|
635
|
-
const customValues: Record<string, unknown> = {}
|
|
636
|
-
Object.entries(record).forEach(([key, value]) => {
|
|
637
|
-
if (key.startsWith('cf_')) customValues[key] = value
|
|
638
|
-
else if (key.startsWith('cf:')) customValues[`cf_${key.slice(3)}`] = value
|
|
639
|
-
})
|
|
640
|
-
return customValues
|
|
641
|
-
}
|
|
642
|
-
|
|
643
635
|
async function syncVariantPricesUpdate({
|
|
644
636
|
priceKinds,
|
|
645
637
|
priceDrafts,
|