@ai-matrx/chat 0.3.27 → 0.3.28
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/CHANGELOG.md +6 -0
- package/dist/agents/hooks/useAgentLauncher.js +4 -3
- package/dist/agents/redux/execution-system/context-rules/request-context.js +5 -1
- package/dist/cx-chat/hooks/useInstanceBootstrap.js +3 -1
- package/dist/host/db-types.d.ts +47 -1
- package/dist/ui/mandates-storage/mandateStorage.d.ts +19 -0
- package/dist/ui/mandates-storage/shortcutStorage.d.ts +38 -0
- package/dist/ui/permission-levels.d.ts +8 -2
- package/dist/ui/permission-levels.js +12 -1
- package/package.json +9 -9
- package/dist/agents/components/shared/AgentDuplicateOutcomeDialog.d.ts +0 -57
- package/dist/agents/components/shared/AgentDuplicateOutcomeDialog.js +0 -188
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
# @ai-matrx/chat
|
|
2
2
|
|
|
3
|
+
## 0.3.28
|
|
4
|
+
|
|
5
|
+
Automatic changed-only republish (docs/metadata drift since the last tag — see
|
|
6
|
+
`git diff npm/chat/v0.3.27..npm/chat/v0.3.28 -- apps/shared/chat`).
|
|
7
|
+
No source changes intended and no consumer action required.
|
|
8
|
+
|
|
3
9
|
## 0.3.27
|
|
4
10
|
|
|
5
11
|
Automatic changed-only republish (docs/metadata drift since the last tag — see
|
|
@@ -22,6 +22,8 @@ import {
|
|
|
22
22
|
} from "../../ui/projectCreateAiDebug.js";
|
|
23
23
|
import { toast } from "../../host/notify.js";
|
|
24
24
|
import { isNotAuthenticatedError } from "../../host/identity.js";
|
|
25
|
+
import { isOrganizationSelectionCancelled } from "../../host/org.js";
|
|
26
|
+
import { launchFailureMessage } from "../redux/execution-system/utils/launch-failure-message.js";
|
|
25
27
|
function isConversationInvocation(options) {
|
|
26
28
|
return "identity" in options && "engine" in options && "routing" in options && "origin" in options;
|
|
27
29
|
}
|
|
@@ -289,6 +291,7 @@ function useAgentLauncher(agentId, optionsInput) {
|
|
|
289
291
|
return;
|
|
290
292
|
}
|
|
291
293
|
if (isNotAuthenticatedError(err)) return;
|
|
294
|
+
if (isOrganizationSelectionCancelled(err)) return;
|
|
292
295
|
if (isProjectCreateFlow(sourceFeature, agentId)) {
|
|
293
296
|
warnProjectCreateAi(
|
|
294
297
|
"useAgentLauncher \u2192 launchAgentExecution FAILED",
|
|
@@ -303,9 +306,7 @@ function useAgentLauncher(agentId, optionsInput) {
|
|
|
303
306
|
} else {
|
|
304
307
|
console.error("Failed to create agent conversation:", err);
|
|
305
308
|
}
|
|
306
|
-
toast.error(
|
|
307
|
-
err instanceof Error && err.message ? err.message : "Failed to start the agent conversation."
|
|
308
|
-
);
|
|
309
|
+
toast.error(launchFailureMessage(err, "Failed to start the agent conversation."));
|
|
309
310
|
});
|
|
310
311
|
return () => {
|
|
311
312
|
launch.wanted = false;
|
|
@@ -371,7 +371,11 @@ const selectDisplayContextRows = (conversationId, mandateKillSwitch = false) =>
|
|
|
371
371
|
}
|
|
372
372
|
const actual = toContextReceipt(receipt);
|
|
373
373
|
const shown = new Set(rows.map((row) => row.key));
|
|
374
|
-
const
|
|
374
|
+
const systemRows = expected ? compareReceipt(expected.rows, actual).systemRows : actual.rows.filter((row) => row.origin !== "client");
|
|
375
|
+
const unsent = [
|
|
376
|
+
...systemRows,
|
|
377
|
+
...actual.rows.filter((row) => isServerAuthoritativeKey(row.key) && !systemRows.includes(row))
|
|
378
|
+
];
|
|
375
379
|
const cap = selectContextInlineCap(state, conversationId);
|
|
376
380
|
const primarySurface = resolveClientSurface(state, conversationId) ?? null;
|
|
377
381
|
const serverAdded = systemRowsToResolved(unsent).filter((row) => !shown.has(row.key)).map((row) => ({
|
|
@@ -10,6 +10,7 @@ import { loadConversation } from "../../agents/redux/execution-system/thunks/loa
|
|
|
10
10
|
import { followWhatIsStillInFlight } from "../../agents/runtime-reconnect/follow-what-is-still-in-flight.js";
|
|
11
11
|
import { toast } from "../../host/notify.js";
|
|
12
12
|
import { isNotAuthenticatedError } from "../../host/identity.js";
|
|
13
|
+
import { isOrganizationSelectionCancelled } from "../../host/org.js";
|
|
13
14
|
import { DEFAULT_AGENT_ID } from "../components/agent/local-agents.js";
|
|
14
15
|
import { replaceAddressWithoutNavigating } from "../../ui/addressWithoutNavigating.js";
|
|
15
16
|
import { ensureAgentCatalog, isAgentCatalogStale } from "../../agents/identity/agent-identity.js";
|
|
@@ -90,7 +91,8 @@ function useInstanceBootstrap() {
|
|
|
90
91
|
resolvedId = result.payload.conversationId;
|
|
91
92
|
instanceByAgentId.current.set(agentId, resolvedId);
|
|
92
93
|
} else if (launchAgentExecution.rejected.match(result) && // Signed out is a state (the sign-in gate), not a failed launch.
|
|
93
|
-
!isNotAuthenticatedError(result.error)
|
|
94
|
+
!isNotAuthenticatedError(result.error) && // A closed organization chooser is the person's "not now", never a failure.
|
|
95
|
+
!isOrganizationSelectionCancelled(result.error)) {
|
|
94
96
|
toast.error(
|
|
95
97
|
result.error.message ?? "Failed to start the agent conversation."
|
|
96
98
|
);
|
package/dist/host/db-types.d.ts
CHANGED
|
@@ -2240,6 +2240,25 @@ export type ChatDatabase = {
|
|
|
2240
2240
|
};
|
|
2241
2241
|
Returns: Json;
|
|
2242
2242
|
};
|
|
2243
|
+
duplicate_agent: {
|
|
2244
|
+
Args: {
|
|
2245
|
+
p_agent_id: string;
|
|
2246
|
+
p_as_system?: boolean;
|
|
2247
|
+
p_follows_source?: boolean;
|
|
2248
|
+
p_name?: string;
|
|
2249
|
+
p_organization_id?: string;
|
|
2250
|
+
};
|
|
2251
|
+
Returns: string;
|
|
2252
|
+
};
|
|
2253
|
+
duplicate_version: {
|
|
2254
|
+
Args: {
|
|
2255
|
+
p_as_system?: boolean;
|
|
2256
|
+
p_name?: string;
|
|
2257
|
+
p_organization_id?: string;
|
|
2258
|
+
p_version_id: string;
|
|
2259
|
+
};
|
|
2260
|
+
Returns: string;
|
|
2261
|
+
};
|
|
2243
2262
|
message_flag_problems: {
|
|
2244
2263
|
Args: never;
|
|
2245
2264
|
Returns: {
|
|
@@ -9789,6 +9808,33 @@ export type ChatDatabase = {
|
|
|
9789
9808
|
};
|
|
9790
9809
|
Relationships: [];
|
|
9791
9810
|
};
|
|
9811
|
+
rag_library_docs_bodies: {
|
|
9812
|
+
Row: {
|
|
9813
|
+
archived_at: string | null;
|
|
9814
|
+
body: string | null;
|
|
9815
|
+
body_hash: string | null;
|
|
9816
|
+
id: string;
|
|
9817
|
+
processed_document_id: string | null;
|
|
9818
|
+
title: string | null;
|
|
9819
|
+
};
|
|
9820
|
+
Insert: {
|
|
9821
|
+
archived_at?: string | null;
|
|
9822
|
+
body?: string | null;
|
|
9823
|
+
body_hash?: string | null;
|
|
9824
|
+
id: string;
|
|
9825
|
+
processed_document_id?: string | null;
|
|
9826
|
+
title?: string | null;
|
|
9827
|
+
};
|
|
9828
|
+
Update: {
|
|
9829
|
+
archived_at?: string | null;
|
|
9830
|
+
body?: string | null;
|
|
9831
|
+
body_hash?: string | null;
|
|
9832
|
+
id?: string;
|
|
9833
|
+
processed_document_id?: string | null;
|
|
9834
|
+
title?: string | null;
|
|
9835
|
+
};
|
|
9836
|
+
Relationships: [];
|
|
9837
|
+
};
|
|
9792
9838
|
research_rs_content_bodies: {
|
|
9793
9839
|
Row: {
|
|
9794
9840
|
archived_at: string;
|
|
@@ -46153,7 +46199,7 @@ export type ChatDatabase = {
|
|
|
46153
46199
|
operation_type: "insert" | "update" | "delete";
|
|
46154
46200
|
org_role: "owner" | "member" | "admin";
|
|
46155
46201
|
orientation: "vertical" | "horizontal" | "default";
|
|
46156
|
-
permission_level: "viewer" | "commenter" | "editor" | "admin";
|
|
46202
|
+
permission_level: "viewer" | "commenter" | "edit_content" | "editor" | "admin";
|
|
46157
46203
|
project_role: "owner" | "admin" | "member";
|
|
46158
46204
|
recipe_status: "live" | "draft" | "in_review" | "active_testing" | "archived" | "other";
|
|
46159
46205
|
reg_func_category: "Recipes" | "Agents" | "Prompts" | "Processors" | "Extractors" | "Files" | "Database" | "Web" | "Media" | "Documents" | "Integrations" | "Commands" | "Executors" | "API" | "Other";
|
|
@@ -10298,6 +10298,25 @@ export declare function mandateNotes(supabase: Client): import("@supabase/supaba
|
|
|
10298
10298
|
};
|
|
10299
10299
|
Returns: Json;
|
|
10300
10300
|
};
|
|
10301
|
+
duplicate_agent: {
|
|
10302
|
+
Args: {
|
|
10303
|
+
p_agent_id: string;
|
|
10304
|
+
p_as_system?: boolean;
|
|
10305
|
+
p_follows_source?: boolean;
|
|
10306
|
+
p_name?: string;
|
|
10307
|
+
p_organization_id?: string;
|
|
10308
|
+
};
|
|
10309
|
+
Returns: string;
|
|
10310
|
+
};
|
|
10311
|
+
duplicate_version: {
|
|
10312
|
+
Args: {
|
|
10313
|
+
p_as_system?: boolean;
|
|
10314
|
+
p_name?: string;
|
|
10315
|
+
p_organization_id?: string;
|
|
10316
|
+
p_version_id: string;
|
|
10317
|
+
};
|
|
10318
|
+
Returns: string;
|
|
10319
|
+
};
|
|
10301
10320
|
message_flag_problems: {
|
|
10302
10321
|
Args: never;
|
|
10303
10322
|
Returns: {
|
|
@@ -1941,6 +1941,25 @@ declare const agentShortcutTable: (supabase: Client) => import("@supabase/supaba
|
|
|
1941
1941
|
};
|
|
1942
1942
|
Returns: import("../../host/db-types.js").Json;
|
|
1943
1943
|
};
|
|
1944
|
+
duplicate_agent: {
|
|
1945
|
+
Args: {
|
|
1946
|
+
p_agent_id: string;
|
|
1947
|
+
p_as_system?: boolean;
|
|
1948
|
+
p_follows_source?: boolean;
|
|
1949
|
+
p_name?: string;
|
|
1950
|
+
p_organization_id?: string;
|
|
1951
|
+
};
|
|
1952
|
+
Returns: string;
|
|
1953
|
+
};
|
|
1954
|
+
duplicate_version: {
|
|
1955
|
+
Args: {
|
|
1956
|
+
p_as_system?: boolean;
|
|
1957
|
+
p_name?: string;
|
|
1958
|
+
p_organization_id?: string;
|
|
1959
|
+
p_version_id: string;
|
|
1960
|
+
};
|
|
1961
|
+
Returns: string;
|
|
1962
|
+
};
|
|
1944
1963
|
message_flag_problems: {
|
|
1945
1964
|
Args: never;
|
|
1946
1965
|
Returns: {
|
|
@@ -4137,6 +4156,25 @@ declare const agentContextMenuView: (supabase: Client) => import("@supabase/supa
|
|
|
4137
4156
|
};
|
|
4138
4157
|
Returns: import("../../host/db-types.js").Json;
|
|
4139
4158
|
};
|
|
4159
|
+
duplicate_agent: {
|
|
4160
|
+
Args: {
|
|
4161
|
+
p_agent_id: string;
|
|
4162
|
+
p_as_system?: boolean;
|
|
4163
|
+
p_follows_source?: boolean;
|
|
4164
|
+
p_name?: string;
|
|
4165
|
+
p_organization_id?: string;
|
|
4166
|
+
};
|
|
4167
|
+
Returns: string;
|
|
4168
|
+
};
|
|
4169
|
+
duplicate_version: {
|
|
4170
|
+
Args: {
|
|
4171
|
+
p_as_system?: boolean;
|
|
4172
|
+
p_name?: string;
|
|
4173
|
+
p_organization_id?: string;
|
|
4174
|
+
p_version_id: string;
|
|
4175
|
+
};
|
|
4176
|
+
Returns: string;
|
|
4177
|
+
};
|
|
4140
4178
|
message_flag_problems: {
|
|
4141
4179
|
Args: never;
|
|
4142
4180
|
Returns: {
|
|
@@ -44,12 +44,18 @@ import type { ChatDatabase as Database } from "../host/db-types.js";
|
|
|
44
44
|
* The canonical ladder, ascending. THE ONE PLACE a level is declared.
|
|
45
45
|
* Order is authority order: each entry outranks every entry before it.
|
|
46
46
|
*/
|
|
47
|
-
export declare const PERMISSION_LEVELS: readonly ["viewer", "commenter", "editor", "admin"];
|
|
47
|
+
export declare const PERMISSION_LEVELS: readonly ["viewer", "commenter", "edit_content", "editor", "admin"];
|
|
48
48
|
export type PermissionLevel = (typeof PERMISSION_LEVELS)[number];
|
|
49
49
|
/** Ordinal rank, 1-based, derived from the ladder so it can never drift. */
|
|
50
50
|
export declare const PERMISSION_LEVEL_RANK: Record<PermissionLevel, number>;
|
|
51
51
|
/** Sentence labels, used where the level is described ("Can view"). */
|
|
52
52
|
export declare const PERMISSION_LEVEL_LABELS: Record<PermissionLevel, string>;
|
|
53
|
+
/**
|
|
54
|
+
* One line each, for a picker's tooltip: what the level lets a person do. `edit_content` is
|
|
55
|
+
* Notion's "Can edit content" - change the rows and page content, never the structure
|
|
56
|
+
* (columns, views, settings) or the sharing. It sorts between `commenter` and `editor`.
|
|
57
|
+
*/
|
|
58
|
+
export declare const PERMISSION_LEVEL_HINTS: Record<PermissionLevel, string>;
|
|
53
59
|
/** Noun labels, used in pickers and chips ("Viewer"). */
|
|
54
60
|
export declare const PERMISSION_LEVEL_SHORT_LABELS: Record<PermissionLevel, string>;
|
|
55
61
|
/**
|
|
@@ -63,7 +69,7 @@ export type DbPermissionLevel = Database["public"]["Enums"]["permission_level"];
|
|
|
63
69
|
* below: when `public.permission_level` gains a value and `pnpm db-types` regenerates, this
|
|
64
70
|
* line stops compiling until the new value is added — never a silent gap.
|
|
65
71
|
*/
|
|
66
|
-
export declare const DB_PERMISSION_LEVELS: readonly ["viewer", "commenter", "editor", "admin"];
|
|
72
|
+
export declare const DB_PERMISSION_LEVELS: readonly ["viewer", "commenter", "edit_content", "editor", "admin"];
|
|
67
73
|
/** Type guard for an arbitrary value being a known code-ladder level. */
|
|
68
74
|
export declare function isPermissionLevel(raw: unknown): raw is PermissionLevel;
|
|
69
75
|
/** True when the database enum can currently store this level. */
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
const PERMISSION_LEVELS = [
|
|
2
2
|
"viewer",
|
|
3
3
|
"commenter",
|
|
4
|
+
"edit_content",
|
|
4
5
|
"editor",
|
|
5
6
|
"admin"
|
|
6
7
|
];
|
|
@@ -10,16 +11,25 @@ const PERMISSION_LEVEL_RANK = Object.fromEntries(
|
|
|
10
11
|
const PERMISSION_LEVEL_LABELS = {
|
|
11
12
|
viewer: "Can view",
|
|
12
13
|
commenter: "Can comment",
|
|
14
|
+
edit_content: "Can edit content",
|
|
13
15
|
editor: "Can edit",
|
|
14
16
|
admin: "Full access"
|
|
15
17
|
};
|
|
18
|
+
const PERMISSION_LEVEL_HINTS = {
|
|
19
|
+
viewer: "Can open and read it.",
|
|
20
|
+
commenter: "Can read it and leave comments.",
|
|
21
|
+
edit_content: "Can change the content, not the structure or the sharing.",
|
|
22
|
+
editor: "Can change content and structure.",
|
|
23
|
+
admin: "Can change everything and decide who else may."
|
|
24
|
+
};
|
|
16
25
|
const PERMISSION_LEVEL_SHORT_LABELS = {
|
|
17
26
|
viewer: "Viewer",
|
|
18
27
|
commenter: "Commenter",
|
|
28
|
+
edit_content: "Content editor",
|
|
19
29
|
editor: "Editor",
|
|
20
30
|
admin: "Full access"
|
|
21
31
|
};
|
|
22
|
-
const DB_PERMISSION_LEVELS = ["viewer", "commenter", "editor", "admin"];
|
|
32
|
+
const DB_PERMISSION_LEVELS = ["viewer", "commenter", "edit_content", "editor", "admin"];
|
|
23
33
|
const _everyDbLevelIsListed = true;
|
|
24
34
|
void _everyDbLevelIsListed;
|
|
25
35
|
function isPermissionLevel(raw) {
|
|
@@ -55,6 +65,7 @@ function permissionLevelRank(level) {
|
|
|
55
65
|
export {
|
|
56
66
|
DB_PERMISSION_LEVELS,
|
|
57
67
|
PERMISSION_LEVELS,
|
|
68
|
+
PERMISSION_LEVEL_HINTS,
|
|
58
69
|
PERMISSION_LEVEL_LABELS,
|
|
59
70
|
PERMISSION_LEVEL_RANK,
|
|
60
71
|
PERMISSION_LEVEL_SHORT_LABELS,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ai-matrx/chat",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.28",
|
|
4
4
|
"description": "THE one AI Matrx person-to-agent chat system: the full chat (running agents, conversations, tool calls, streaming, context, surfaces, voice) as per-module subpaths @ai-matrx/chat/<domain>/<module> over a host contract (/host, /host/react) whose only required value is a db; plus the kernel compatibility entries (., /external-store, /matrx, /react, /tools, styles.css, tokens.css) until P28.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.cjs",
|
|
@@ -230,20 +230,20 @@
|
|
|
230
230
|
"@ai-matrx/associations": "latest",
|
|
231
231
|
"@ai-matrx/browser-audio": "latest",
|
|
232
232
|
"@ai-matrx/canvas": "latest",
|
|
233
|
-
"@ai-matrx/content-ir
|
|
233
|
+
"@ai-matrx/content-ir": "latest",
|
|
234
234
|
"@ai-matrx/agents": "latest",
|
|
235
|
-
"@ai-matrx/
|
|
235
|
+
"@ai-matrx/content-ir-react": "latest",
|
|
236
|
+
"@ai-matrx/data": "latest",
|
|
236
237
|
"@ai-matrx/diff": "latest",
|
|
238
|
+
"@ai-matrx/design-system": "latest",
|
|
237
239
|
"@ai-matrx/icons": "latest",
|
|
240
|
+
"@ai-matrx/kit": "latest",
|
|
241
|
+
"@ai-matrx/media": "latest",
|
|
238
242
|
"@ai-matrx/print": "latest",
|
|
239
243
|
"@ai-matrx/realtime": "latest",
|
|
240
|
-
"@ai-matrx/media": "latest",
|
|
241
|
-
"@ai-matrx/records": "latest",
|
|
242
|
-
"@ai-matrx/tap-target": "latest",
|
|
243
244
|
"@ai-matrx/records-ui": "latest",
|
|
244
|
-
"@ai-matrx/
|
|
245
|
-
"@ai-matrx/
|
|
246
|
-
"@ai-matrx/kit": "latest"
|
|
245
|
+
"@ai-matrx/records": "latest",
|
|
246
|
+
"@ai-matrx/tap-target": "latest"
|
|
247
247
|
},
|
|
248
248
|
"devDependencies": {
|
|
249
249
|
"@arethetypeswrong/cli": "^0.18.5",
|
|
@@ -1,57 +0,0 @@
|
|
|
1
|
-
/** "choose" = the person picks which version to copy before anything runs. */
|
|
2
|
-
export type DuplicateOutcomeState = "choose" | "loading" | "success" | "error";
|
|
3
|
-
/** The value of the "copy the agent as it is now" choice. */
|
|
4
|
-
export declare const CURRENT_VERSION_CHOICE = "current";
|
|
5
|
-
export interface DuplicateVersionOption {
|
|
6
|
-
versionId: string;
|
|
7
|
-
versionNumber: number;
|
|
8
|
-
changedAt: string;
|
|
9
|
-
changeNote: string | null;
|
|
10
|
-
}
|
|
11
|
-
export interface DuplicateVersionChooser {
|
|
12
|
-
/** The source agent's live version number, shown on the default choice. */
|
|
13
|
-
currentVersion: number | null;
|
|
14
|
-
/** Saved past versions, newest first. */
|
|
15
|
-
versions: DuplicateVersionOption[];
|
|
16
|
-
versionsLoading: boolean;
|
|
17
|
-
/** Set when the version list could not be read — the current version still works. */
|
|
18
|
-
versionsError: string | null;
|
|
19
|
-
/** CURRENT_VERSION_CHOICE or a version id. */
|
|
20
|
-
selected: string;
|
|
21
|
-
onSelectedChange: (value: string) => void;
|
|
22
|
-
onConfirm: () => void;
|
|
23
|
-
}
|
|
24
|
-
export interface AgentDuplicateOutcomeDialogProps {
|
|
25
|
-
open: boolean;
|
|
26
|
-
/** Called when the user dismisses the dialog (X button, escape, or "Stay
|
|
27
|
-
* here"). The dialog is fully controlled — the parent owns lifecycle. */
|
|
28
|
-
onOpenChange: (open: boolean) => void;
|
|
29
|
-
state: DuplicateOutcomeState;
|
|
30
|
-
/** Display name of the new agent (only meaningful in success state). */
|
|
31
|
-
newAgentName?: string;
|
|
32
|
-
/** Path to the new agent — used by both "Open new agent" and "Open in new
|
|
33
|
-
* tab." Defaults to `null` while loading; required in success state. */
|
|
34
|
-
newAgentPath?: string | null;
|
|
35
|
-
/** Optional error message in error state. */
|
|
36
|
-
errorMessage?: string;
|
|
37
|
-
/** Whether the source agent was a builtin/system agent. Tweaks the success
|
|
38
|
-
* copy so admins know the duplicate is also a system agent. */
|
|
39
|
-
asSystem?: boolean;
|
|
40
|
-
/** Required for the "choose" state. */
|
|
41
|
-
chooser?: DuplicateVersionChooser;
|
|
42
|
-
}
|
|
43
|
-
/**
|
|
44
|
-
* Post-duplicate "where would you like to go?" choice surface.
|
|
45
|
-
*
|
|
46
|
-
* Flow:
|
|
47
|
-
* 1. Parent fires the duplicate thunk and immediately mounts this dialog
|
|
48
|
-
* with `state="loading"` so the user sees the in-flight work.
|
|
49
|
-
* 2. On success, the parent flips to `state="success"` and supplies the
|
|
50
|
-
* new agent's id + computed `newAgentPath`. The user picks one of three
|
|
51
|
-
* destinations (open in current tab, open in new tab, stay here).
|
|
52
|
-
* 3. On failure, the parent flips to `state="error"` with a message.
|
|
53
|
-
*
|
|
54
|
-
* Mobile renders as a bottom Drawer (per project mobile rules — never Dialog
|
|
55
|
-
* on mobile); desktop uses a small Dialog (`sm:max-w-md`).
|
|
56
|
-
*/
|
|
57
|
-
export declare function AgentDuplicateOutcomeDialog({ open, onOpenChange, state, newAgentName, newAgentPath, errorMessage, asSystem, chooser, }: AgentDuplicateOutcomeDialogProps): import("react").JSX.Element;
|
|
@@ -1,188 +0,0 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
import { jsx, jsxs } from "react/jsx-runtime";
|
|
3
|
-
import { useTransition } from "react";
|
|
4
|
-
import { useRouter } from "../../../host/navigation.js";
|
|
5
|
-
import {
|
|
6
|
-
AlertCircle,
|
|
7
|
-
ArrowRight,
|
|
8
|
-
CheckCircle2,
|
|
9
|
-
Copy,
|
|
10
|
-
ExternalLink,
|
|
11
|
-
Loader2
|
|
12
|
-
} from "lucide-react";
|
|
13
|
-
import {
|
|
14
|
-
Dialog,
|
|
15
|
-
DialogContent,
|
|
16
|
-
DialogDescription,
|
|
17
|
-
DialogHeader,
|
|
18
|
-
DialogTitle
|
|
19
|
-
} from "@ai-matrx/design-system";
|
|
20
|
-
import {
|
|
21
|
-
Drawer,
|
|
22
|
-
DrawerContent,
|
|
23
|
-
DrawerDescription,
|
|
24
|
-
DrawerHeader,
|
|
25
|
-
DrawerTitle
|
|
26
|
-
} from "@ai-matrx/design-system";
|
|
27
|
-
import { Alert, AlertDescription } from "@ai-matrx/design-system";
|
|
28
|
-
import { Button } from "@ai-matrx/design-system";
|
|
29
|
-
import { Select } from "@ai-matrx/design-system/controls";
|
|
30
|
-
import { useIsMobile } from "@ai-matrx/kit/media-query";
|
|
31
|
-
const CURRENT_VERSION_CHOICE = "current";
|
|
32
|
-
function AgentDuplicateOutcomeDialog({
|
|
33
|
-
open,
|
|
34
|
-
onOpenChange,
|
|
35
|
-
state,
|
|
36
|
-
newAgentName,
|
|
37
|
-
newAgentPath,
|
|
38
|
-
errorMessage,
|
|
39
|
-
asSystem = false,
|
|
40
|
-
chooser
|
|
41
|
-
}) {
|
|
42
|
-
const isMobile = useIsMobile();
|
|
43
|
-
const router = useRouter();
|
|
44
|
-
const [isNavigating, startTransition] = useTransition();
|
|
45
|
-
const handleGoToAgent = () => {
|
|
46
|
-
if (!newAgentPath) return;
|
|
47
|
-
onOpenChange(false);
|
|
48
|
-
startTransition(() => router.push(newAgentPath));
|
|
49
|
-
};
|
|
50
|
-
const handleOpenInNewTab = () => {
|
|
51
|
-
if (!newAgentPath) return;
|
|
52
|
-
window.open(newAgentPath, "_blank", "noopener,noreferrer");
|
|
53
|
-
onOpenChange(false);
|
|
54
|
-
};
|
|
55
|
-
const handleStayHere = () => {
|
|
56
|
-
onOpenChange(false);
|
|
57
|
-
};
|
|
58
|
-
const titleText = state === "choose" ? "Duplicate agent" : state === "loading" ? "Duplicating agent\u2026" : state === "success" ? asSystem ? "System agent duplicated" : "Agent duplicated" : "Duplicate failed";
|
|
59
|
-
const descriptionText = state === "choose" ? "Pick the version to copy into a new agent." : state === "loading" ? "Creating a copy with all messages, variables, settings, and tools." : state === "success" ? newAgentName ? `"${newAgentName}" is ready. Where would you like to go?` : "The copy is ready. Where would you like to go?" : errorMessage ?? "Something went wrong while duplicating.";
|
|
60
|
-
const body = /* @__PURE__ */ jsxs("div", { className: "space-y-4", children: [
|
|
61
|
-
state === "choose" && chooser && /* @__PURE__ */ jsxs("div", { className: "space-y-3", children: [
|
|
62
|
-
/* @__PURE__ */ jsx(
|
|
63
|
-
Select,
|
|
64
|
-
{
|
|
65
|
-
"aria-label": "Version to copy",
|
|
66
|
-
className: "w-full",
|
|
67
|
-
value: chooser.selected,
|
|
68
|
-
onValueChange: chooser.onSelectedChange,
|
|
69
|
-
options: [
|
|
70
|
-
{
|
|
71
|
-
value: CURRENT_VERSION_CHOICE,
|
|
72
|
-
label: chooser.currentVersion != null ? `Current version (v${chooser.currentVersion})` : "Current version"
|
|
73
|
-
},
|
|
74
|
-
...chooser.versions.filter((v) => v.versionNumber !== chooser.currentVersion).map((v) => ({ value: v.versionId, label: versionOptionLabel(v) }))
|
|
75
|
-
]
|
|
76
|
-
}
|
|
77
|
-
),
|
|
78
|
-
chooser.versionsLoading && /* @__PURE__ */ jsxs("p", { className: "flex items-center gap-2 text-xs text-muted-foreground", children: [
|
|
79
|
-
/* @__PURE__ */ jsx(Loader2, { className: "h-3 w-3 animate-spin" }),
|
|
80
|
-
"Loading versions\u2026"
|
|
81
|
-
] }),
|
|
82
|
-
chooser.versionsError && /* @__PURE__ */ jsxs("p", { className: "text-xs text-destructive", children: [
|
|
83
|
-
"Past versions could not be loaded: ",
|
|
84
|
-
chooser.versionsError
|
|
85
|
-
] }),
|
|
86
|
-
/* @__PURE__ */ jsxs("div", { className: "flex justify-end gap-2", children: [
|
|
87
|
-
/* @__PURE__ */ jsx(Button, { variant: "ghost", onClick: handleStayHere, children: "Cancel" }),
|
|
88
|
-
/* @__PURE__ */ jsxs(Button, { onClick: chooser.onConfirm, children: [
|
|
89
|
-
/* @__PURE__ */ jsx(Copy, { className: "h-4 w-4" }),
|
|
90
|
-
"Duplicate"
|
|
91
|
-
] })
|
|
92
|
-
] })
|
|
93
|
-
] }),
|
|
94
|
-
state === "loading" && /* @__PURE__ */ jsxs("div", { className: "flex flex-col items-center gap-3 py-6", children: [
|
|
95
|
-
/* @__PURE__ */ jsx(Loader2, { className: "h-10 w-10 animate-spin text-primary" }),
|
|
96
|
-
/* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground", children: "Please wait\u2026" })
|
|
97
|
-
] }),
|
|
98
|
-
state === "success" && /* @__PURE__ */ jsxs("div", { className: "space-y-3", children: [
|
|
99
|
-
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3 p-3 rounded-md bg-success/10 border border-success/20", children: [
|
|
100
|
-
/* @__PURE__ */ jsx(CheckCircle2, { className: "h-5 w-5 text-success shrink-0" }),
|
|
101
|
-
/* @__PURE__ */ jsx("p", { className: "text-sm font-medium", children: "Copy created successfully." })
|
|
102
|
-
] }),
|
|
103
|
-
/* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-2", children: [
|
|
104
|
-
/* @__PURE__ */ jsxs(
|
|
105
|
-
Button,
|
|
106
|
-
{
|
|
107
|
-
size: "lg",
|
|
108
|
-
onClick: handleGoToAgent,
|
|
109
|
-
disabled: !newAgentPath || isNavigating,
|
|
110
|
-
className: "w-full justify-start gap-2",
|
|
111
|
-
children: [
|
|
112
|
-
isNavigating ? /* @__PURE__ */ jsx(Loader2, { className: "h-4 w-4 animate-spin" }) : /* @__PURE__ */ jsx(ArrowRight, { className: "h-4 w-4" }),
|
|
113
|
-
/* @__PURE__ */ jsx("span", { className: "flex-1 text-left", children: "Open new agent" })
|
|
114
|
-
]
|
|
115
|
-
}
|
|
116
|
-
),
|
|
117
|
-
newAgentPath ? /* @__PURE__ */ jsxs(
|
|
118
|
-
Button,
|
|
119
|
-
{
|
|
120
|
-
size: "lg",
|
|
121
|
-
variant: "outline",
|
|
122
|
-
onClick: handleOpenInNewTab,
|
|
123
|
-
className: "w-full justify-start gap-2",
|
|
124
|
-
children: [
|
|
125
|
-
/* @__PURE__ */ jsx(ExternalLink, { className: "h-4 w-4" }),
|
|
126
|
-
/* @__PURE__ */ jsx("span", { className: "flex-1 text-left", children: "Open in new tab" })
|
|
127
|
-
]
|
|
128
|
-
}
|
|
129
|
-
) : null,
|
|
130
|
-
/* @__PURE__ */ jsxs(
|
|
131
|
-
Button,
|
|
132
|
-
{
|
|
133
|
-
size: "lg",
|
|
134
|
-
variant: "ghost",
|
|
135
|
-
onClick: handleStayHere,
|
|
136
|
-
className: "w-full justify-start gap-2",
|
|
137
|
-
children: [
|
|
138
|
-
/* @__PURE__ */ jsx(Copy, { className: "h-4 w-4" }),
|
|
139
|
-
/* @__PURE__ */ jsx("span", { className: "flex-1 text-left", children: "Stay here" })
|
|
140
|
-
]
|
|
141
|
-
}
|
|
142
|
-
)
|
|
143
|
-
] })
|
|
144
|
-
] }),
|
|
145
|
-
state === "error" && /* @__PURE__ */ jsxs("div", { className: "space-y-3", children: [
|
|
146
|
-
/* @__PURE__ */ jsxs(Alert, { variant: "destructive", children: [
|
|
147
|
-
/* @__PURE__ */ jsx(AlertCircle, { className: "h-4 w-4" }),
|
|
148
|
-
/* @__PURE__ */ jsx(AlertDescription, { children: errorMessage ?? "Failed to duplicate agent." })
|
|
149
|
-
] }),
|
|
150
|
-
/* @__PURE__ */ jsx(Button, { variant: "outline", onClick: handleStayHere, className: "w-full", children: "Close" })
|
|
151
|
-
] })
|
|
152
|
-
] });
|
|
153
|
-
if (isMobile) {
|
|
154
|
-
return /* @__PURE__ */ jsx(Drawer, { open, onOpenChange, children: /* @__PURE__ */ jsxs(DrawerContent, { className: "max-h-[85dvh] pb-safe", children: [
|
|
155
|
-
/* @__PURE__ */ jsxs(DrawerHeader, { children: [
|
|
156
|
-
/* @__PURE__ */ jsxs(DrawerTitle, { className: "flex items-center gap-2", children: [
|
|
157
|
-
/* @__PURE__ */ jsx(Copy, { className: "h-5 w-5" }),
|
|
158
|
-
titleText
|
|
159
|
-
] }),
|
|
160
|
-
/* @__PURE__ */ jsx(DrawerDescription, { children: descriptionText })
|
|
161
|
-
] }),
|
|
162
|
-
/* @__PURE__ */ jsx("div", { className: "px-4 pb-4", children: body })
|
|
163
|
-
] }) });
|
|
164
|
-
}
|
|
165
|
-
return /* @__PURE__ */ jsx(Dialog, { open, onOpenChange, children: /* @__PURE__ */ jsxs(DialogContent, { className: "sm:max-w-md", children: [
|
|
166
|
-
/* @__PURE__ */ jsxs(DialogHeader, { children: [
|
|
167
|
-
/* @__PURE__ */ jsxs(DialogTitle, { className: "flex items-center gap-2", children: [
|
|
168
|
-
/* @__PURE__ */ jsx(Copy, { className: "h-5 w-5" }),
|
|
169
|
-
titleText
|
|
170
|
-
] }),
|
|
171
|
-
/* @__PURE__ */ jsx(DialogDescription, { children: descriptionText })
|
|
172
|
-
] }),
|
|
173
|
-
body
|
|
174
|
-
] }) });
|
|
175
|
-
}
|
|
176
|
-
function versionOptionLabel(v) {
|
|
177
|
-
const date = new Date(v.changedAt).toLocaleDateString(void 0, {
|
|
178
|
-
month: "short",
|
|
179
|
-
day: "numeric",
|
|
180
|
-
year: "numeric"
|
|
181
|
-
});
|
|
182
|
-
const note = v.changeNote?.trim();
|
|
183
|
-
return note ? `v${v.versionNumber} \xB7 ${date} \xB7 ${note.length > 40 ? `${note.slice(0, 40)}\u2026` : note}` : `v${v.versionNumber} \xB7 ${date}`;
|
|
184
|
-
}
|
|
185
|
-
export {
|
|
186
|
-
AgentDuplicateOutcomeDialog,
|
|
187
|
-
CURRENT_VERSION_CHOICE
|
|
188
|
-
};
|