@gui-chat-plugin/switch-role 0.1.0

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/README.md ADDED
@@ -0,0 +1,79 @@
1
+ # @gui-chat-plugin/switch-role
2
+
3
+ [![npm version](https://badge.fury.io/js/%40gui-chat-plugin%2Fswitch-role.svg)](https://www.npmjs.com/package/@gui-chat-plugin/switch-role)
4
+
5
+ A switch-role plugin for [MulmoChat](https://github.com/receptron/MulmoChat).
6
+
7
+ ## Overview
8
+
9
+ This plugin allows users to switch between different AI assistant roles/personas during a conversation. Each role can have different system prompts and available plugins.
10
+
11
+ ## Installation
12
+
13
+ ```bash
14
+ yarn add @gui-chat-plugin/switch-role
15
+ ```
16
+
17
+ ## Usage
18
+
19
+ ### Vue Implementation (for MulmoChat)
20
+
21
+ ```typescript
22
+ // In src/tools/index.ts
23
+ import SwitchRolePlugin from "@gui-chat-plugin/switch-role/vue";
24
+
25
+ const pluginList = [
26
+ // ... other plugins
27
+ SwitchRolePlugin,
28
+ ];
29
+
30
+ // In src/main.ts
31
+ import "@gui-chat-plugin/switch-role/style.css";
32
+ ```
33
+
34
+ ### Core Only (Framework-agnostic)
35
+
36
+ ```typescript
37
+ import { pluginCore, TOOL_NAME, setRoles, getRoles } from "@gui-chat-plugin/switch-role";
38
+ ```
39
+
40
+ ### Configuring Roles
41
+
42
+ ```typescript
43
+ import { setRoles } from "@gui-chat-plugin/switch-role";
44
+
45
+ setRoles([
46
+ { id: "assistant", name: "General Assistant" },
47
+ { id: "coder", name: "Coding Expert" },
48
+ { id: "writer", name: "Creative Writer" },
49
+ ]);
50
+ ```
51
+
52
+ ## Package Exports
53
+
54
+ | Export | Description |
55
+ |--------|-------------|
56
+ | `@gui-chat-plugin/switch-role` | Core (framework-agnostic) |
57
+ | `@gui-chat-plugin/switch-role/vue` | Vue implementation |
58
+ | `@gui-chat-plugin/switch-role/style.css` | Tailwind CSS styles |
59
+
60
+ ## Test Prompts
61
+
62
+ 1. "Switch to the coding assistant role"
63
+ 2. "Change to the creative writer persona"
64
+ 3. "What roles are available?"
65
+ 4. "Switch role to listener"
66
+
67
+ ## Development
68
+
69
+ ```bash
70
+ yarn install
71
+ yarn dev # Start dev server
72
+ yarn build # Build
73
+ yarn typecheck # Type check
74
+ yarn lint # Lint
75
+ ```
76
+
77
+ ## License
78
+
79
+ MIT
@@ -0,0 +1,12 @@
1
+ /**
2
+ * SwitchRole Tool Definition (Schema)
3
+ */
4
+ import type { ToolDefinition } from "gui-chat-protocol";
5
+ export declare const TOOL_NAME = "switchRole";
6
+ /**
7
+ * Create tool definition with current roles
8
+ * This needs to be called dynamically since roles can be configured
9
+ */
10
+ export declare function createToolDefinition(): ToolDefinition;
11
+ export declare const TOOL_DEFINITION: ToolDefinition;
12
+ export declare const SYSTEM_PROMPT = "When users ask to change the role, personality, or behavior of the AI (e.g., 'switch to tutor role', 'change to listener role', 'be a teacher'), use the switchRole function. Note that switching roles will disconnect and reconnect the conversation.";
@@ -0,0 +1,6 @@
1
+ /**
2
+ * SwitchRole Plugin - Core (Framework-agnostic)
3
+ */
4
+ export type { Role, SwitchRoleArgs, SwitchRoleJsonData } from "./types";
5
+ export { DEFAULT_ROLES, setRoles, getRoles, getRoleById } from "./roles";
6
+ export { TOOL_NAME, TOOL_DEFINITION, SYSTEM_PROMPT, createToolDefinition, executeSwitchRole, pluginCore, } from "./plugin";
@@ -0,0 +1,13 @@
1
+ /**
2
+ * SwitchRole Plugin Core (Framework-agnostic)
3
+ */
4
+ import type { ToolPluginCore, ToolContext, ToolResult } from "gui-chat-protocol";
5
+ import type { SwitchRoleArgs, SwitchRoleJsonData } from "./types";
6
+ export { TOOL_NAME, TOOL_DEFINITION, SYSTEM_PROMPT, createToolDefinition } from "./definition";
7
+ export { DEFAULT_ROLES, setRoles, getRoles, getRoleById } from "./roles";
8
+ /**
9
+ * Execute the switchRole function
10
+ * Triggers a role switch via the app layer
11
+ */
12
+ export declare const executeSwitchRole: (_context: ToolContext, args: SwitchRoleArgs) => Promise<ToolResult<unknown, SwitchRoleJsonData>>;
13
+ export declare const pluginCore: ToolPluginCore<unknown, SwitchRoleJsonData, SwitchRoleArgs>;
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Default roles configuration
3
+ * These can be overridden by the app layer
4
+ */
5
+ import type { Role } from "./types";
6
+ export declare const DEFAULT_ROLES: Role[];
7
+ export declare function setRoles(roles: Role[]): void;
8
+ export declare function getRoles(): Role[];
9
+ export declare function getRoleById(id: string): Role | undefined;
@@ -0,0 +1,20 @@
1
+ /**
2
+ * SwitchRole Plugin Types
3
+ */
4
+ /** Role definition */
5
+ export interface Role {
6
+ id: string;
7
+ name: string;
8
+ }
9
+ /** Arguments passed to the switchRole tool */
10
+ export interface SwitchRoleArgs {
11
+ role: string;
12
+ }
13
+ /** JSON data returned in result.jsonData (sent to LLM) */
14
+ export interface SwitchRoleJsonData {
15
+ success: boolean;
16
+ role?: string;
17
+ roleName?: string;
18
+ error?: string;
19
+ availableRoles?: Role[];
20
+ }
package/dist/core.cjs ADDED
@@ -0,0 +1 @@
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const c=[{id:"general",name:"General"},{id:"tutor",name:"Tutor"},{id:"listener",name:"Listener"},{id:"receptionist",name:"Receptionist"},{id:"tourPlanner",name:"Trip Planner"},{id:"recipeGuide",name:"Recipe Guide"},{id:"game",name:"Game"},{id:"office",name:"Office"}];let r=c;function p(o){r=o}function s(){return r}function u(o){return r.find(i=>i.id===o)}const a="switchRole";function h(){const o=s(),i=o.map(n=>n.id),t=o.map(n=>`'${n.id}' (${n.name})`).join(", ");return{type:"function",name:a,description:`Switch the system prompt role and reconnect to the LLM. This changes the AI's personality and behavior. Available roles: ${t}.`,parameters:{type:"object",properties:{role:{type:"string",enum:i,description:`The role to switch to. Options: ${t}`}},required:["role"]}}}const d=h(),m=`When users ask to change the role, personality, or behavior of the AI (e.g., 'switch to tutor role', 'change to listener role', 'be a teacher'), use the ${a} function. Note that switching roles will disconnect and reconnect the conversation.`,g=async(o,i)=>{const{role:t}=i,n=s(),f=n.map(e=>`${e.id} (${e.name})`).join(", ");try{const e=u(t);if(!e)return{message:`Invalid role: ${t}`,jsonData:{success:!1,error:"Invalid role",availableRoles:n},instructions:`Tell the user that '${t}' is not a valid role. Available roles are: ${f}.`};const l=globalThis;if(typeof window<"u"&&typeof l.switchRole=="function")setTimeout(()=>{l.switchRole?.(t)},0);else return console.error("switchRole function not found on window object"),{message:"Failed to switch role: switchRole API not available",jsonData:{success:!1,error:"switchRole API not available"},instructions:"Tell the user that the role switching feature is not available."};return{message:`Role switch to '${e.name}' initiated`,jsonData:{success:!0,role:t,roleName:e.name}}}catch(e){return console.error("ERR: exception in switchRole",e),{message:`Role switch error: ${e instanceof Error?e.message:"Unknown error"}`,jsonData:{success:!1,error:e instanceof Error?e.message:"Unknown error"},instructions:"Acknowledge that there was an error switching roles and ask the user to try again."}}},R={toolDefinition:d,execute:g,generatingMessage:"Switching role...",isEnabled:()=>!0,systemPrompt:m};exports.DEFAULT_ROLES=c;exports.SYSTEM_PROMPT=m;exports.TOOL_DEFINITION=d;exports.TOOL_NAME=a;exports.createToolDefinition=h;exports.executeSwitchRole=g;exports.getRoleById=u;exports.getRoles=s;exports.pluginCore=R;exports.setRoles=p;
package/dist/core.js ADDED
@@ -0,0 +1,105 @@
1
+ const u = [
2
+ { id: "general", name: "General" },
3
+ { id: "tutor", name: "Tutor" },
4
+ { id: "listener", name: "Listener" },
5
+ { id: "receptionist", name: "Receptionist" },
6
+ { id: "tourPlanner", name: "Trip Planner" },
7
+ { id: "recipeGuide", name: "Recipe Guide" },
8
+ { id: "game", name: "Game" },
9
+ { id: "office", name: "Office" }
10
+ ];
11
+ let s = u;
12
+ function g(o) {
13
+ s = o;
14
+ }
15
+ function a() {
16
+ return s;
17
+ }
18
+ function h(o) {
19
+ return s.find((r) => r.id === o);
20
+ }
21
+ const l = "switchRole";
22
+ function d() {
23
+ const o = a(), r = o.map((n) => n.id), t = o.map((n) => `'${n.id}' (${n.name})`).join(", ");
24
+ return {
25
+ type: "function",
26
+ name: l,
27
+ description: `Switch the system prompt role and reconnect to the LLM. This changes the AI's personality and behavior. Available roles: ${t}.`,
28
+ parameters: {
29
+ type: "object",
30
+ properties: {
31
+ role: {
32
+ type: "string",
33
+ enum: r,
34
+ description: `The role to switch to. Options: ${t}`
35
+ }
36
+ },
37
+ required: ["role"]
38
+ }
39
+ };
40
+ }
41
+ const m = d(), f = `When users ask to change the role, personality, or behavior of the AI (e.g., 'switch to tutor role', 'change to listener role', 'be a teacher'), use the ${l} function. Note that switching roles will disconnect and reconnect the conversation.`, p = async (o, r) => {
42
+ const { role: t } = r, n = a(), c = n.map((e) => `${e.id} (${e.name})`).join(", ");
43
+ try {
44
+ const e = h(t);
45
+ if (!e)
46
+ return {
47
+ message: `Invalid role: ${t}`,
48
+ jsonData: {
49
+ success: !1,
50
+ error: "Invalid role",
51
+ availableRoles: n
52
+ },
53
+ instructions: `Tell the user that '${t}' is not a valid role. Available roles are: ${c}.`
54
+ };
55
+ const i = globalThis;
56
+ if (typeof window < "u" && typeof i.switchRole == "function")
57
+ setTimeout(() => {
58
+ i.switchRole?.(t);
59
+ }, 0);
60
+ else
61
+ return console.error("switchRole function not found on window object"), {
62
+ message: "Failed to switch role: switchRole API not available",
63
+ jsonData: {
64
+ success: !1,
65
+ error: "switchRole API not available"
66
+ },
67
+ instructions: "Tell the user that the role switching feature is not available."
68
+ };
69
+ return {
70
+ message: `Role switch to '${e.name}' initiated`,
71
+ jsonData: {
72
+ success: !0,
73
+ role: t,
74
+ roleName: e.name
75
+ }
76
+ };
77
+ } catch (e) {
78
+ return console.error("ERR: exception in switchRole", e), {
79
+ message: `Role switch error: ${e instanceof Error ? e.message : "Unknown error"}`,
80
+ jsonData: {
81
+ success: !1,
82
+ error: e instanceof Error ? e.message : "Unknown error"
83
+ },
84
+ instructions: "Acknowledge that there was an error switching roles and ask the user to try again."
85
+ };
86
+ }
87
+ }, w = {
88
+ toolDefinition: m,
89
+ execute: p,
90
+ generatingMessage: "Switching role...",
91
+ isEnabled: () => !0,
92
+ systemPrompt: f
93
+ };
94
+ export {
95
+ u as DEFAULT_ROLES,
96
+ f as SYSTEM_PROMPT,
97
+ m as TOOL_DEFINITION,
98
+ l as TOOL_NAME,
99
+ d as createToolDefinition,
100
+ p as executeSwitchRole,
101
+ h as getRoleById,
102
+ a as getRoles,
103
+ w as pluginCore,
104
+ g as setRoles
105
+ };
package/dist/index.cjs ADDED
@@ -0,0 +1 @@
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("./core.cjs");exports.DEFAULT_ROLES=e.DEFAULT_ROLES;exports.SYSTEM_PROMPT=e.SYSTEM_PROMPT;exports.TOOL_DEFINITION=e.TOOL_DEFINITION;exports.TOOL_NAME=e.TOOL_NAME;exports.createToolDefinition=e.createToolDefinition;exports.executeSwitchRole=e.executeSwitchRole;exports.getRoleById=e.getRoleById;exports.getRoles=e.getRoles;exports.pluginCore=e.pluginCore;exports.setRoles=e.setRoles;
@@ -0,0 +1,6 @@
1
+ /**
2
+ * SwitchRole Plugin
3
+ *
4
+ * Main entry point - re-exports core module.
5
+ */
6
+ export * from "./core";
package/dist/index.js ADDED
@@ -0,0 +1,13 @@
1
+ import { DEFAULT_ROLES as t, SYSTEM_PROMPT as O, TOOL_DEFINITION as T, TOOL_NAME as l, createToolDefinition as R, executeSwitchRole as i, getRoleById as E, getRoles as r, pluginCore as I, setRoles as L } from "./core.js";
2
+ export {
3
+ t as DEFAULT_ROLES,
4
+ O as SYSTEM_PROMPT,
5
+ T as TOOL_DEFINITION,
6
+ l as TOOL_NAME,
7
+ R as createToolDefinition,
8
+ i as executeSwitchRole,
9
+ E as getRoleById,
10
+ r as getRoles,
11
+ I as pluginCore,
12
+ L as setRoles
13
+ };
package/dist/style.css ADDED
@@ -0,0 +1 @@
1
+ @layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-space-y-reverse:0;--tw-border-style:solid;--tw-font-weight:initial;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000}}}@layer theme{:root,:host{--font-sans:ui-sans-serif,system-ui,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";--font-mono:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;--color-red-500:oklch(63.7% .237 25.331);--color-red-600:oklch(57.7% .245 27.325);--color-green-500:oklch(72.3% .219 149.579);--color-emerald-50:oklch(97.9% .021 166.113);--color-emerald-100:oklch(95% .052 163.051);--color-emerald-200:oklch(90.5% .093 164.15);--color-emerald-800:oklch(43.2% .095 166.913);--color-indigo-100:oklch(93% .034 272.788);--color-indigo-200:oklch(87% .065 274.039);--color-indigo-300:oklch(78.5% .115 274.713);--color-indigo-500:oklch(58.5% .233 277.117);--color-indigo-600:oklch(51.1% .262 276.966);--color-indigo-700:oklch(45.7% .24 277.023);--color-purple-400:oklch(71.4% .203 305.504);--color-purple-600:oklch(55.8% .288 302.321);--color-gray-50:oklch(98.5% .002 247.839);--color-gray-100:oklch(96.7% .003 264.542);--color-gray-200:oklch(92.8% .006 264.531);--color-gray-300:oklch(87.2% .01 258.338);--color-gray-400:oklch(70.7% .022 261.325);--color-gray-500:oklch(55.1% .027 264.364);--color-gray-600:oklch(44.6% .03 256.802);--color-gray-700:oklch(37.3% .034 259.733);--color-gray-800:oklch(27.8% .033 256.848);--color-white:#fff;--spacing:.25rem;--container-3xl:48rem;--text-xs:.75rem;--text-xs--line-height:calc(1/.75);--text-sm:.875rem;--text-sm--line-height:calc(1.25/.875);--text-xl:1.25rem;--text-xl--line-height:calc(1.75/1.25);--font-weight-medium:500;--radius-md:.375rem;--radius-lg:.5rem;--default-transition-duration:.15s;--default-transition-timing-function:cubic-bezier(.4,0,.2,1);--default-font-family:var(--font-sans);--default-mono-font-family:var(--font-mono)}}@layer base{*,:after,:before,::backdrop{box-sizing:border-box;border:0 solid;margin:0;padding:0}::file-selector-button{box-sizing:border-box;border:0 solid;margin:0;padding:0}html,:host{-webkit-text-size-adjust:100%;tab-size:4;line-height:1.5;font-family:var(--default-font-family,ui-sans-serif,system-ui,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji");font-feature-settings:var(--default-font-feature-settings,normal);font-variation-settings:var(--default-font-variation-settings,normal);-webkit-tap-highlight-color:transparent}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:var(--default-mono-font-family,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace);font-feature-settings:var(--default-mono-font-feature-settings,normal);font-variation-settings:var(--default-mono-font-variation-settings,normal);font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}:-moz-focusring{outline:auto}progress{vertical-align:baseline}summary{display:list-item}ol,ul,menu{list-style:none}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}button,input,select,optgroup,textarea{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}::file-selector-button{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}:where(select:is([multiple],[size])) optgroup{font-weight:bolder}:where(select:is([multiple],[size])) optgroup option{padding-inline-start:20px}::file-selector-button{margin-inline-end:4px}::placeholder{opacity:1}@supports (not ((-webkit-appearance:-apple-pay-button))) or (contain-intrinsic-size:1px){::placeholder{color:currentColor}@supports (color:color-mix(in lab,red,red)){::placeholder{color:color-mix(in oklab,currentcolor 50%,transparent)}}}textarea{resize:vertical}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-date-and-time-value{min-height:1lh;text-align:inherit}::-webkit-datetime-edit{display:inline-flex}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-datetime-edit{padding-block:0}::-webkit-datetime-edit-year-field{padding-block:0}::-webkit-datetime-edit-month-field{padding-block:0}::-webkit-datetime-edit-day-field{padding-block:0}::-webkit-datetime-edit-hour-field{padding-block:0}::-webkit-datetime-edit-minute-field{padding-block:0}::-webkit-datetime-edit-second-field{padding-block:0}::-webkit-datetime-edit-millisecond-field{padding-block:0}::-webkit-datetime-edit-meridiem-field{padding-block:0}::-webkit-calendar-picker-indicator{line-height:1}:-moz-ui-invalid{box-shadow:none}button,input:where([type=button],[type=reset],[type=submit]){appearance:button}::file-selector-button{appearance:button}::-webkit-inner-spin-button{height:auto}::-webkit-outer-spin-button{height:auto}[hidden]:where(:not([hidden=until-found])){display:none!important}}@layer components;@layer utilities{.m-0{margin:calc(var(--spacing)*0)}.mx-auto{margin-inline:auto}.mt-3{margin-top:calc(var(--spacing)*3)}.mt-4{margin-top:calc(var(--spacing)*4)}.mb-2{margin-bottom:calc(var(--spacing)*2)}.mb-3{margin-bottom:calc(var(--spacing)*3)}.mb-4{margin-bottom:calc(var(--spacing)*4)}.mb-5{margin-bottom:calc(var(--spacing)*5)}.mb-8{margin-bottom:calc(var(--spacing)*8)}.block{display:block}.contents{display:contents}.flex{display:flex}.h-4{height:calc(var(--spacing)*4)}.w-4{width:calc(var(--spacing)*4)}.w-full{width:100%}.max-w-3xl{max-width:var(--container-3xl)}.max-w-\[200px\]{max-width:200px}.cursor-pointer{cursor:pointer}.resize-y{resize:vertical}.flex-wrap{flex-wrap:wrap}.items-center{align-items:center}.gap-1{gap:calc(var(--spacing)*1)}.gap-2{gap:calc(var(--spacing)*2)}.gap-3{gap:calc(var(--spacing)*3)}:where(.space-y-1>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing)*1)*var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing)*1)*calc(1 - var(--tw-space-y-reverse)))}.overflow-x-auto{overflow-x:auto}.rounded{border-radius:.25rem}.rounded-lg{border-radius:var(--radius-lg)}.rounded-md{border-radius:var(--radius-md)}.border{border-style:var(--tw-border-style);border-width:1px}.border-none{--tw-border-style:none;border-style:none}.border-emerald-200{border-color:var(--color-emerald-200)}.border-gray-200{border-color:var(--color-gray-200)}.border-gray-300{border-color:var(--color-gray-300)}.border-indigo-200{border-color:var(--color-indigo-200)}.bg-emerald-50{background-color:var(--color-emerald-50)}.bg-emerald-100{background-color:var(--color-emerald-100)}.bg-gray-50{background-color:var(--color-gray-50)}.bg-gray-100{background-color:var(--color-gray-100)}.bg-indigo-100{background-color:var(--color-indigo-100)}.bg-indigo-600{background-color:var(--color-indigo-600)}.bg-white{background-color:var(--color-white)}.p-2{padding:calc(var(--spacing)*2)}.p-3{padding:calc(var(--spacing)*3)}.p-4{padding:calc(var(--spacing)*4)}.p-5{padding:calc(var(--spacing)*5)}.px-4{padding-inline:calc(var(--spacing)*4)}.px-6{padding-inline:calc(var(--spacing)*6)}.py-2{padding-block:calc(var(--spacing)*2)}.py-2\.5{padding-block:calc(var(--spacing)*2.5)}.font-mono{font-family:var(--font-mono)}.text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.text-xl{font-size:var(--text-xl);line-height:var(--tw-leading,var(--text-xl--line-height))}.text-xs{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.font-medium{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.whitespace-pre-wrap{white-space:pre-wrap}.text-emerald-800{color:var(--color-emerald-800)}.text-gray-500{color:var(--color-gray-500)}.text-gray-600{color:var(--color-gray-600)}.text-gray-700{color:var(--color-gray-700)}.text-gray-800{color:var(--color-gray-800)}.text-green-500{color:var(--color-green-500)}.text-indigo-700{color:var(--color-indigo-700)}.text-purple-600{color:var(--color-purple-600)}.text-red-500{color:var(--color-red-500)}.text-red-600{color:var(--color-red-600)}.text-white{color:var(--color-white)}.shadow-md{--tw-shadow:0 4px 6px -1px var(--tw-shadow-color,#0000001a),0 2px 4px -2px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.transition-all{transition-property:all;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-colors{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}@media(hover:hover){.hover\:border-indigo-300:hover{border-color:var(--color-indigo-300)}.hover\:bg-indigo-200:hover{background-color:var(--color-indigo-200)}.hover\:bg-indigo-700:hover{background-color:var(--color-indigo-700)}}.focus\:border-indigo-500:focus{border-color:var(--color-indigo-500)}.focus\:ring-\[3px\]:focus{--tw-ring-shadow:var(--tw-ring-inset,)0 0 0 calc(3px + var(--tw-ring-offset-width))var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.focus\:ring-indigo-500\/10:focus{--tw-ring-color:#625fff1a}@supports (color:color-mix(in lab,red,red)){.focus\:ring-indigo-500\/10:focus{--tw-ring-color:color-mix(in oklab,var(--color-indigo-500)10%,transparent)}}.focus\:outline-none:focus{--tw-outline-style:none;outline-style:none}@media(prefers-color-scheme:dark){.dark\:bg-gray-800{background-color:var(--color-gray-800)}.dark\:text-gray-300{color:var(--color-gray-300)}.dark\:text-gray-400{color:var(--color-gray-400)}.dark\:text-purple-400{color:var(--color-purple-400)}}}body{margin:calc(var(--spacing)*0);background-color:var(--color-gray-100);padding:calc(var(--spacing)*5);font-family:var(--font-sans)}@property --tw-space-y-reverse{syntax:"*";inherits:false;initial-value:0}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-font-weight{syntax:"*";inherits:false}@property --tw-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-shadow-color{syntax:"*";inherits:false}@property --tw-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-inset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-shadow-color{syntax:"*";inherits:false}@property --tw-inset-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-ring-color{syntax:"*";inherits:false}@property --tw-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-ring-color{syntax:"*";inherits:false}@property --tw-inset-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-ring-inset{syntax:"*";inherits:false}@property --tw-ring-offset-width{syntax:"<length>";inherits:false;initial-value:0}@property --tw-ring-offset-color{syntax:"*";inherits:false;initial-value:#fff}@property --tw-ring-offset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}
@@ -0,0 +1,8 @@
1
+ import type { ToolResult } from "gui-chat-protocol";
2
+ import type { SwitchRoleJsonData } from "../core/types";
3
+ type __VLS_Props = {
4
+ result: ToolResult<unknown, SwitchRoleJsonData>;
5
+ };
6
+ declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
7
+ declare const _default: typeof __VLS_export;
8
+ export default _default;
@@ -0,0 +1,15 @@
1
+ /**
2
+ * SwitchRole Plugin - Vue Implementation
3
+ */
4
+ import "../style.css";
5
+ import type { ToolPlugin } from "gui-chat-protocol/vue";
6
+ import type { SwitchRoleArgs, SwitchRoleJsonData } from "../core/types";
7
+ import Preview from "./Preview.vue";
8
+ export declare const plugin: ToolPlugin<unknown, SwitchRoleJsonData, SwitchRoleArgs>;
9
+ export type { Role, SwitchRoleArgs, SwitchRoleJsonData } from "../core/types";
10
+ export { TOOL_NAME, TOOL_DEFINITION, SYSTEM_PROMPT, createToolDefinition, executeSwitchRole, pluginCore, DEFAULT_ROLES, setRoles, getRoles, getRoleById, } from "../core/plugin";
11
+ export { Preview };
12
+ declare const _default: {
13
+ plugin: ToolPlugin<unknown, SwitchRoleJsonData, SwitchRoleArgs, import("gui-chat-protocol/vue").InputHandler, Record<string, unknown>>;
14
+ };
15
+ export default _default;
package/dist/vue.cjs ADDED
@@ -0,0 +1 @@
1
+ "use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const t=require("./core.cjs"),e=require("vue"),d={class:"p-2 bg-gray-50 dark:bg-gray-800 rounded"},u={class:"text-xs text-gray-600 dark:text-gray-400"},p={key:0,class:"space-y-1"},m={class:"flex items-center gap-1"},g={class:"font-medium"},v={class:"text-xs text-gray-500"},E={key:1,class:"flex items-center gap-1 text-red-500"},n=e.defineComponent({__name:"Preview",props:{result:{}},setup(a){const s=a,c=e.computed(()=>s.result.jsonData?.success||!1),l=e.computed(()=>s.result.jsonData?.roleName||"Unknown"),i=e.computed(()=>s.result.jsonData?.error);return(x,o)=>(e.openBlock(),e.createElementBlock("div",d,[o[2]||(o[2]=e.createElementVNode("div",{class:"flex items-center gap-2 mb-2"},[e.createElementVNode("svg",{xmlns:"http://www.w3.org/2000/svg",class:"h-4 w-4 text-purple-600 dark:text-purple-400",viewBox:"0 0 20 20",fill:"currentColor"},[e.createElementVNode("path",{"fill-rule":"evenodd",d:"M4 2a1 1 0 011 1v2.101a7.002 7.002 0 0111.601 2.566 1 1 0 11-1.885.666A5.002 5.002 0 005.999 7H9a1 1 0 010 2H4a1 1 0 01-1-1V3a1 1 0 011-1zm.008 9.057a1 1 0 011.276.61A5.002 5.002 0 0014.001 13H11a1 1 0 110-2h5a1 1 0 011 1v5a1 1 0 11-2 0v-2.101a7.002 7.002 0 01-11.601-2.566 1 1 0 01.61-1.276z","clip-rule":"evenodd"})]),e.createElementVNode("span",{class:"text-sm font-medium text-gray-700 dark:text-gray-300"}," Role Switch ")],-1)),e.createElementVNode("div",u,[c.value?(e.openBlock(),e.createElementBlock("div",p,[e.createElementVNode("div",m,[o[0]||(o[0]=e.createElementVNode("span",{class:"text-green-500"},"✓",-1)),e.createElementVNode("span",g,e.toDisplayString(l.value),1)]),e.createElementVNode("div",v,"Switched to "+e.toDisplayString(l.value)+" role",1)])):(e.openBlock(),e.createElementBlock("div",E,[o[1]||(o[1]=e.createElementVNode("span",null,"✗",-1)),e.createElementVNode("span",null,e.toDisplayString(i.value||"Failed to switch role"),1)]))])]))}}),r={...t.pluginCore,previewComponent:n},_={plugin:r};exports.DEFAULT_ROLES=t.DEFAULT_ROLES;exports.SYSTEM_PROMPT=t.SYSTEM_PROMPT;exports.TOOL_DEFINITION=t.TOOL_DEFINITION;exports.TOOL_NAME=t.TOOL_NAME;exports.createToolDefinition=t.createToolDefinition;exports.executeSwitchRole=t.executeSwitchRole;exports.getRoleById=t.getRoleById;exports.getRoles=t.getRoles;exports.pluginCore=t.pluginCore;exports.setRoles=t.setRoles;exports.Preview=n;exports.default=_;exports.plugin=r;
package/dist/vue.js ADDED
@@ -0,0 +1,66 @@
1
+ import { pluginCore as p } from "./core.js";
2
+ import { DEFAULT_ROLES as T, SYSTEM_PROMPT as N, TOOL_DEFINITION as M, TOOL_NAME as A, createToolDefinition as B, executeSwitchRole as C, getRoleById as I, getRoles as L, setRoles as P } from "./core.js";
3
+ import { defineComponent as u, computed as o, createElementBlock as a, openBlock as r, createElementVNode as e, toDisplayString as l } from "vue";
4
+ const m = { class: "p-2 bg-gray-50 dark:bg-gray-800 rounded" }, x = { class: "text-xs text-gray-600 dark:text-gray-400" }, g = {
5
+ key: 0,
6
+ class: "space-y-1"
7
+ }, v = { class: "flex items-center gap-1" }, _ = { class: "font-medium" }, f = { class: "text-xs text-gray-500" }, w = {
8
+ key: 1,
9
+ class: "flex items-center gap-1 text-red-500"
10
+ }, y = /* @__PURE__ */ u({
11
+ __name: "Preview",
12
+ props: {
13
+ result: {}
14
+ },
15
+ setup(i) {
16
+ const s = i, c = o(() => s.result.jsonData?.success || !1), n = o(() => s.result.jsonData?.roleName || "Unknown"), d = o(() => s.result.jsonData?.error);
17
+ return (k, t) => (r(), a("div", m, [
18
+ t[2] || (t[2] = e("div", { class: "flex items-center gap-2 mb-2" }, [
19
+ e("svg", {
20
+ xmlns: "http://www.w3.org/2000/svg",
21
+ class: "h-4 w-4 text-purple-600 dark:text-purple-400",
22
+ viewBox: "0 0 20 20",
23
+ fill: "currentColor"
24
+ }, [
25
+ e("path", {
26
+ "fill-rule": "evenodd",
27
+ d: "M4 2a1 1 0 011 1v2.101a7.002 7.002 0 0111.601 2.566 1 1 0 11-1.885.666A5.002 5.002 0 005.999 7H9a1 1 0 010 2H4a1 1 0 01-1-1V3a1 1 0 011-1zm.008 9.057a1 1 0 011.276.61A5.002 5.002 0 0014.001 13H11a1 1 0 110-2h5a1 1 0 011 1v5a1 1 0 11-2 0v-2.101a7.002 7.002 0 01-11.601-2.566 1 1 0 01.61-1.276z",
28
+ "clip-rule": "evenodd"
29
+ })
30
+ ]),
31
+ e("span", { class: "text-sm font-medium text-gray-700 dark:text-gray-300" }, " Role Switch ")
32
+ ], -1)),
33
+ e("div", x, [
34
+ c.value ? (r(), a("div", g, [
35
+ e("div", v, [
36
+ t[0] || (t[0] = e("span", { class: "text-green-500" }, "✓", -1)),
37
+ e("span", _, l(n.value), 1)
38
+ ]),
39
+ e("div", f, "Switched to " + l(n.value) + " role", 1)
40
+ ])) : (r(), a("div", w, [
41
+ t[1] || (t[1] = e("span", null, "✗", -1)),
42
+ e("span", null, l(d.value || "Failed to switch role"), 1)
43
+ ]))
44
+ ])
45
+ ]));
46
+ }
47
+ }), h = {
48
+ ...p,
49
+ previewComponent: y
50
+ // No viewComponent - this plugin only has a preview
51
+ }, O = { plugin: h };
52
+ export {
53
+ T as DEFAULT_ROLES,
54
+ y as Preview,
55
+ N as SYSTEM_PROMPT,
56
+ M as TOOL_DEFINITION,
57
+ A as TOOL_NAME,
58
+ B as createToolDefinition,
59
+ O as default,
60
+ C as executeSwitchRole,
61
+ I as getRoleById,
62
+ L as getRoles,
63
+ h as plugin,
64
+ p as pluginCore,
65
+ P as setRoles
66
+ };
package/package.json ADDED
@@ -0,0 +1,63 @@
1
+ {
2
+ "name": "@gui-chat-plugin/switch-role",
3
+ "version": "0.1.0",
4
+ "description": "Switch role plugin for GUIChat",
5
+ "type": "module",
6
+ "main": "./dist/index.cjs",
7
+ "module": "./dist/index.js",
8
+ "types": "./dist/index.d.ts",
9
+ "exports": {
10
+ ".": {
11
+ "types": "./dist/index.d.ts",
12
+ "import": "./dist/index.js",
13
+ "require": "./dist/index.cjs"
14
+ },
15
+ "./core": {
16
+ "types": "./dist/core/index.d.ts",
17
+ "import": "./dist/core.js",
18
+ "require": "./dist/core.cjs"
19
+ },
20
+ "./vue": {
21
+ "types": "./dist/vue/index.d.ts",
22
+ "import": "./dist/vue.js",
23
+ "require": "./dist/vue.cjs"
24
+ },
25
+ "./style.css": "./dist/style.css"
26
+ },
27
+ "files": [
28
+ "dist"
29
+ ],
30
+ "scripts": {
31
+ "dev": "vite",
32
+ "build": "vite build && vue-tsc -p tsconfig.build.json --emitDeclarationOnly",
33
+ "typecheck": "vue-tsc --noEmit",
34
+ "lint": "eslint src demo"
35
+ },
36
+ "peerDependencies": {
37
+ "gui-chat-protocol": "^0.0.1",
38
+ "vue": "^3.5.0"
39
+ },
40
+ "devDependencies": {
41
+ "@tailwindcss/vite": "^4.1.18",
42
+ "@typescript-eslint/eslint-plugin": "^8.53.0",
43
+ "@typescript-eslint/parser": "^8.53.0",
44
+ "@vitejs/plugin-vue": "^6.0.3",
45
+ "eslint": "^9.39.2",
46
+ "eslint-plugin-vue": "^10.6.2",
47
+ "globals": "^17.0.0",
48
+ "gui-chat-protocol": "^0.0.1",
49
+ "tailwindcss": "^4.1.18",
50
+ "typescript": "~5.9.3",
51
+ "vite": "^7.3.1",
52
+ "vue": "^3.5.27",
53
+ "vue-eslint-parser": "^10.2.0",
54
+ "vue-tsc": "^3.2.2"
55
+ },
56
+ "keywords": [
57
+ "guichat",
58
+ "plugin",
59
+ "role",
60
+ "switch"
61
+ ],
62
+ "license": "MIT"
63
+ }