crow-central-agency 0.26.11 → 0.26.13

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.
Files changed (47) hide show
  1. package/dist/_shared/index.js +3 -3
  2. package/dist/_shared/schemas/agent.schema.js +42 -1
  3. package/dist/_shared/schemas/artifact.schema.js +24 -3
  4. package/dist/_shared/utils/resolve-model.js +6 -1
  5. package/dist/mcp/gmail/create-gmail-draft.js +9 -3
  6. package/dist/mcp/gmail/reply-to-gmail-message.js +8 -5
  7. package/dist/mcp/gmail/send-gmail-message.js +8 -5
  8. package/dist/mcp/gmail/update-gmail-draft.js +10 -1
  9. package/dist/public/assets/{architectureDiagram-3BPJPVTR-Dfu4mDxF.js → architectureDiagram-3BPJPVTR-Bt4tuNX8.js} +1 -1
  10. package/dist/public/assets/{chunk-727SXJPM-DRdyIpFH.js → chunk-727SXJPM-BjjXmWC5.js} +1 -1
  11. package/dist/public/assets/{chunk-AQP2D5EJ-CxdFOJqZ.js → chunk-AQP2D5EJ-DjJ_-SOd.js} +1 -1
  12. package/dist/public/assets/{classDiagram-v2-Q7XG4LA2-LI64xNQq.js → classDiagram-4FO5ZUOK-DVPqtO0x.js} +1 -1
  13. package/dist/public/assets/{classDiagram-4FO5ZUOK-LI64xNQq.js → classDiagram-v2-Q7XG4LA2-DVPqtO0x.js} +1 -1
  14. package/dist/public/assets/{dagre-BM42HDAG-BejrWpgw.js → dagre-BM42HDAG-CZBf8H9_.js} +1 -1
  15. package/dist/public/assets/{diagram-2AECGRRQ-CYSDU7Es.js → diagram-2AECGRRQ-C_U6a4go.js} +1 -1
  16. package/dist/public/assets/{diagram-5GNKFQAL-CWqg_--c.js → diagram-5GNKFQAL-Bk-3tHvA.js} +1 -1
  17. package/dist/public/assets/{diagram-LMA3HP47-DVIh9QtC.js → diagram-LMA3HP47-JxZtWEor.js} +1 -1
  18. package/dist/public/assets/{diagram-OG6HWLK6-B5AgbZto.js → diagram-OG6HWLK6-BJ1F3Sxu.js} +1 -1
  19. package/dist/public/assets/{erDiagram-TEJ5UH35-C_nNA82y.js → erDiagram-TEJ5UH35-BJBHxTf8.js} +1 -1
  20. package/dist/public/assets/{flowDiagram-I6XJVG4X-By2qp00o.js → flowDiagram-I6XJVG4X-DJ3nm5z7.js} +1 -1
  21. package/dist/public/assets/index-BJmLehUe.js +505 -0
  22. package/dist/public/assets/index-BqakLGSS.css +1 -0
  23. package/dist/public/assets/{infoDiagram-5YYISTIA-CVHdXYSW.js → infoDiagram-5YYISTIA-Cc1k7k1c.js} +1 -1
  24. package/dist/public/assets/{ishikawaDiagram-YF4QCWOH-BL-2W-LS.js → ishikawaDiagram-YF4QCWOH-DrDraHBD.js} +1 -1
  25. package/dist/public/assets/{kanban-definition-UN3LZRKU-xSoJwokp.js → kanban-definition-UN3LZRKU-CNUMfAVC.js} +1 -1
  26. package/dist/public/assets/{mindmap-definition-RKZ34NQL-DqGauYKP.js → mindmap-definition-RKZ34NQL-DOeL-Iu4.js} +1 -1
  27. package/dist/public/assets/{pieDiagram-4H26LBE5-Cem-YV-o.js → pieDiagram-4H26LBE5-DCP9wuZK.js} +1 -1
  28. package/dist/public/assets/{requirementDiagram-4Y6WPE33-B9aiHS8X.js → requirementDiagram-4Y6WPE33-7UzZpq-C.js} +1 -1
  29. package/dist/public/assets/{sequenceDiagram-3UESZ5HK-yWsOSX3M.js → sequenceDiagram-3UESZ5HK-D5alEu9E.js} +1 -1
  30. package/dist/public/assets/{stateDiagram-AJRCARHV-DukGMuPG.js → stateDiagram-AJRCARHV-EkSeb-RA.js} +1 -1
  31. package/dist/public/assets/{stateDiagram-v2-BHNVJYJU-D9OyrL7B.js → stateDiagram-v2-BHNVJYJU-DmpUDd8s.js} +1 -1
  32. package/dist/public/assets/{timeline-definition-PNZ67QCA-BsTDDrEU.js → timeline-definition-PNZ67QCA-B4oLmMT1.js} +1 -1
  33. package/dist/public/assets/{vennDiagram-CIIHVFJN-s98Cc7wd.js → vennDiagram-CIIHVFJN-DgiGQ7rE.js} +1 -1
  34. package/dist/public/assets/{wardleyDiagram-YWT4CUSO-Y4ycH63u.js → wardleyDiagram-YWT4CUSO-dDWLWZoc.js} +1 -1
  35. package/dist/public/assets/{xychartDiagram-2RQKCTM6-DZ5QZsxL.js → xychartDiagram-2RQKCTM6-TOELm0t1.js} +1 -1
  36. package/dist/public/index.html +2 -2
  37. package/dist/routes/artifact.routes.js +24 -19
  38. package/dist/runner/claude-code-agent-runner.js +27 -1
  39. package/dist/runner/github-copilot-agent-runner.js +32 -1
  40. package/dist/services/agent-registry.js +10 -1
  41. package/dist/services/artifact/artifact-manager.js +3 -0
  42. package/dist/services/google/google-client.js +15 -10
  43. package/dist/services/google/google-client.types.js +4 -0
  44. package/dist/services/google/resolve-email-body-parts.js +15 -0
  45. package/package.json +2 -2
  46. package/dist/public/assets/index-BsTDVaFe.js +0 -505
  47. package/dist/public/assets/index-DwcUOyrO.css +0 -1
@@ -1,11 +1,11 @@
1
- export { CLAUDE_MODELS, GITHUB_COPILOT_MODELS, CLAUDE_CODE_MODEL_OPTIONS, ModelOptionSchema, REASONING_EFFORT, ReasoningEffortSchema, CLAUDE_DEFAULT_MODEL, COPILOT_DEFAULT_MODEL, AgentIdSchema, AgentConfigSchema, AgentConfigTemplateSchema, CreateAgentInputSchema, UpdateAgentInputSchema, ToolConfigSchema, PermissionModeSchema, SettingSourceSchema, DiscoveredSkillSchema, LoopConfigSchema, ConfiguredFeedSchema, MAX_LOOP_TIMES, PERMISSION_MODE, SETTING_SOURCE, DEFAULT_SETTING_SOURCES, TOOL_MODE, CLAUDE_CODE_TOOL, GITHUB_COPILOT_TOOL, DEFAULT_CLAUDE_CODE_AVAILABLE_TOOLS, DEFAULT_GITHUB_COPILOT_AVAILABLE_TOOLS, DEFAULT_AVAILABLE_TOOLS_BY_TYPE, SUBAGENT_TOOL_NAME, AGENT_TYPE, AgentTypeSchema, DEFAULT_AGENT_TYPE, AGENT_NAME_MAX_LENGTH, } from "./schemas/agent.schema.js";
1
+ export { CLAUDE_MODELS, GITHUB_COPILOT_MODELS, CLAUDE_CODE_MODEL_OPTIONS, ModelOptionSchema, REASONING_EFFORT, ReasoningEffortSchema, THINKING_MODE, CLAUDE_DEFAULT_MODEL, COPILOT_DEFAULT_MODEL, CLAUDE_AUTO_COMPACT_TOKENS_MIN, CLAUDE_AUTO_COMPACT_TOKENS_MAX, COPILOT_AUTO_COMPACT_UTILIZATION_MAX, AgentIdSchema, AgentConfigSchema, AgentConfigTemplateSchema, CreateAgentInputSchema, UpdateAgentInputSchema, ToolConfigSchema, PermissionModeSchema, SettingSourceSchema, DiscoveredSkillSchema, LoopConfigSchema, ConfiguredFeedSchema, MAX_LOOP_TIMES, PERMISSION_MODE, SETTING_SOURCE, DEFAULT_SETTING_SOURCES, TOOL_MODE, CLAUDE_CODE_TOOL, GITHUB_COPILOT_TOOL, DEFAULT_CLAUDE_CODE_AVAILABLE_TOOLS, DEFAULT_GITHUB_COPILOT_AVAILABLE_TOOLS, DEFAULT_AVAILABLE_TOOLS_BY_TYPE, SUBAGENT_TOOL_NAME, AGENT_TYPE, AgentTypeSchema, DEFAULT_AGENT_TYPE, AGENT_NAME_MAX_LENGTH, } from "./schemas/agent.schema.js";
2
2
  export { SchedulerTimeSchema, DAY_OF_WEEK, DayOfWeekSchema, TimeModeSchema, TIME_MODE, } from "./schemas/scheduler.schema.js";
3
3
  export { createApiSuccessSchema, ApiErrorSchema, } from "./schemas/api-response.schema.js";
4
4
  export { SessionUsageSchema, PendingPermissionInfoSchema, PendingInstructionReminderSchema, AgentRuntimeStateSchema, AgentActivitySchema, AGENT_ACTIVITY_TYPE, AGENT_STATUS, MAX_INPUT_HISTORY, } from "./schemas/agent-runtime-state.schema.js";
5
5
  export { ClientMessageSchema, ServerMessageSchema, SendMessageSchema, InjectMessageSchema, PermissionResponseWsSchema, CommandMessageSchema, AgentTextWsMessageSchema, AgentActivityWsMessageSchema, AgentResultWsMessageSchema, AgentStatusWsMessageSchema, AgentCreatedWsMessageSchema, AgentUpdatedWsMessageSchema, AgentDeletedWsMessageSchema, AgentUsageWsMessageSchema, PermissionRequestWsMessageSchema, PermissionCancelledWsMessageSchema, ErrorWsMessageSchema, AgentMessageWsMessageSchema, AgentToolProgressWsMessageSchema, TaskAddedWsMessageSchema, TaskUpdatedWsMessageSchema, TaskAssignedWsMessageSchema, TaskStateChangedWsMessageSchema, TaskDeletedWsMessageSchema, CircleCreatedWsMessageSchema, CircleUpdatedWsMessageSchema, CircleDeletedWsMessageSchema, RelationshipCreatedWsMessageSchema, RelationshipDeletedWsMessageSchema, AgentBuilderDraftUpdatedWsMessageSchema, isAgentServerMessage, CLIENT_MESSAGE_TYPE, SERVER_MESSAGE_TYPE, } from "./schemas/websocket.schema.js";
6
6
  export { PERMISSION_DECISION, PermissionRequestSchema, PermissionResponseSchema, } from "./schemas/permission.schema.js";
7
7
  export { AgentMessageSchema, MessageAnnotationSchema, AGENT_MESSAGE_ROLE, AGENT_MESSAGE_TYPE, } from "./schemas/agent-message.schema.js";
8
- export { ARTIFACT_TYPE, ARTIFACT_CONTENT_TYPE, ArtifactTypeSchema, ArtifactContentTypeSchema, ArtifactMetadataSchema, ArtifactTagsUpdateSchema, } from "./schemas/artifact.schema.js";
8
+ export { ARTIFACT_TYPE, ARTIFACT_CONTENT_TYPE, ArtifactTypeSchema, ArtifactContentTypeSchema, ArtifactMetadataSchema, ArtifactUpdateSchema, } from "./schemas/artifact.schema.js";
9
9
  export { AGENT_TASK_STATE, AGENT_TASK_SOURCE_TYPE, AgentTaskStateSchema, AgentTaskSourceSchema, AgentTaskItemSchema, AgentTaskDatabaseSchema, CreateTaskInputSchema, UpdateTaskInputSchema, UpdateTaskStateInputSchema, AssignTaskInputSchema, } from "./schemas/agent-task.schema.js";
10
10
  export { MCP_CONFIG_TYPE, InternalMcpConfigSchema, McpServerConfigSchema, CreateMcpConfigInputSchema, UpdateMcpConfigInputSchema, } from "./schemas/mcp-config.schema.js";
11
11
  export { SensorInfoSchema } from "./schemas/sensor.schema.js";
@@ -16,7 +16,7 @@ export { SystemCapabilitiesSchema } from "./schemas/system-capabilities.schema.j
16
16
  export { GENERATION_TYPE, GenerationTypeSchema, GenerateRequestSchema, } from "./schemas/generation.schema.js";
17
17
  export { AGENT_BUILDER_LIMITS, AGENT_BUILDER_WORD_BUDGET, AGENT_BUILDER_DRAFT_STATUS, AgentBuilderDraftStatusSchema, AgentBuilderBuiltAgentSchema, AgentBuilderBuildResultSchema, FleetAgentSchema, FleetResponseSchema, AgentBuilderDraftSchema, AgentBuilderDesignRequestSchema, AgentBuilderPatchRequestSchema, FleetNamedRefSchema, FleetAgentViewSchema, AgentBuilderDraftViewSchema, AgentBuilderDraftResponseSchema, AgentBuilderDraftMutationResponseSchema, } from "./schemas/agent-builder.schema.js";
18
18
  export { applyAgentOrder } from "./utils/apply-agent-order.js";
19
- export { MODEL_ALIASES, resolveModel } from "./utils/resolve-model.js";
19
+ export { MODEL_ALIASES, resolveModel, modelSupportsAdaptiveThinking } from "./utils/resolve-model.js";
20
20
  export { BASE_CIRCLE_ID, BASE_CIRCLE_NAME } from "./constants/system-circle.js";
21
21
  export { ENTITY_TYPE, RELATIONSHIP_TYPE, AgentCircleSchema, CreateAgentCircleInputSchema, UpdateAgentCircleInputSchema, EntityTypeSchema, RelationshipTypeSchema, RelationshipSchema, CreateRelationshipInputSchema, CircleMemberSchema, } from "./schemas/agent-circle.schema.js";
22
22
  export { CROW_SYSTEM_AGENT_ID, CROW_TASK_DISPATCHER_AGENT_ID, CROW_NARRATIVE_ARCHITECT_AGENT_ID, CROW_WORLD_BUILDER_AGENT_ID, } from "./constants/system-agent.js";
@@ -37,23 +37,37 @@ export const ReasoningEffortSchema = z.enum([
37
37
  REASONING_EFFORT.XHIGH,
38
38
  REASONING_EFFORT.MAX,
39
39
  ]);
40
+ export const THINKING_MODE = {
41
+ ENABLED: "enabled",
42
+ DISABLED: "disabled",
43
+ ADAPTIVE: "adaptive",
44
+ };
45
+ export const ThinkingModeSchema = z.enum([THINKING_MODE.ENABLED, THINKING_MODE.DISABLED, THINKING_MODE.ADAPTIVE]);
46
+ /** Extended-thinking control for Claude Code agents; budget applies only to `enabled` mode. */
47
+ export const AgentThinkingConfigSchema = z.object({
48
+ mode: ThinkingModeSchema,
49
+ budget: z.number().int().positive().optional(),
50
+ });
40
51
  /** A selectable agent model, surfaced to the editor's model picker. */
41
52
  export const ModelOptionSchema = z.object({
42
53
  value: z.string(),
43
54
  label: z.string(),
44
55
  /** Reasoning effort levels the model supports; omitted when the model has no effort control. */
45
56
  supportedEfforts: z.array(ReasoningEffortSchema).optional(),
57
+ supportsAdaptiveThinking: z.boolean().optional(),
46
58
  });
47
59
  export const CLAUDE_CODE_MODEL_OPTIONS = [
48
60
  {
49
61
  value: CLAUDE_MODELS.SONNET,
50
62
  label: "Claude Sonnet 5",
51
63
  supportedEfforts: [REASONING_EFFORT.LOW, REASONING_EFFORT.MEDIUM, REASONING_EFFORT.HIGH, REASONING_EFFORT.MAX],
64
+ supportsAdaptiveThinking: true,
52
65
  },
53
66
  {
54
67
  value: CLAUDE_MODELS.SONNET_4_6,
55
68
  label: "Claude Sonnet 4.6",
56
69
  supportedEfforts: [REASONING_EFFORT.LOW, REASONING_EFFORT.MEDIUM, REASONING_EFFORT.HIGH, REASONING_EFFORT.MAX],
70
+ supportsAdaptiveThinking: true,
57
71
  },
58
72
  {
59
73
  value: CLAUDE_MODELS.OPUS,
@@ -65,6 +79,7 @@ export const CLAUDE_CODE_MODEL_OPTIONS = [
65
79
  REASONING_EFFORT.XHIGH,
66
80
  REASONING_EFFORT.MAX,
67
81
  ],
82
+ supportsAdaptiveThinking: true,
68
83
  },
69
84
  {
70
85
  value: CLAUDE_MODELS.OPUS_4_7,
@@ -76,6 +91,7 @@ export const CLAUDE_CODE_MODEL_OPTIONS = [
76
91
  REASONING_EFFORT.XHIGH,
77
92
  REASONING_EFFORT.MAX,
78
93
  ],
94
+ supportsAdaptiveThinking: true,
79
95
  },
80
96
  { value: CLAUDE_MODELS.HAIKU, label: "Claude Haiku 4.5" },
81
97
  {
@@ -88,6 +104,7 @@ export const CLAUDE_CODE_MODEL_OPTIONS = [
88
104
  REASONING_EFFORT.XHIGH,
89
105
  REASONING_EFFORT.MAX,
90
106
  ],
107
+ supportsAdaptiveThinking: true,
91
108
  },
92
109
  ];
93
110
  /** Default model for new agents */
@@ -277,6 +294,23 @@ export const AgentVoiceConfigSchema = z.object({
277
294
  voiceName: z.string().optional(),
278
295
  stylePrompt: z.string().optional(),
279
296
  });
297
+ /**
298
+ * Bounds the Claude Code SDK enforces on its auto-compact window (`int().min(1e5).max(1e6)`);
299
+ * out-of-range values are silently dropped by the SDK, so we validate against the same range.
300
+ */
301
+ export const CLAUDE_AUTO_COMPACT_TOKENS_MIN = 100000;
302
+ export const CLAUDE_AUTO_COMPACT_TOKENS_MAX = 1000000;
303
+ /** GitHub Copilot's background-compaction threshold is a fraction (0-1) of the context window. */
304
+ export const COPILOT_AUTO_COMPACT_UTILIZATION_MAX = 1;
305
+ /**
306
+ * Manual auto-compaction thresholds. `tokensThreshold` drives Claude Code (context token count),
307
+ * `utilizationThreshold` drives GitHub Copilot (0-1 fraction of the context window). Each provider
308
+ * reads only its own field; an unset config leaves the provider's default behavior in place.
309
+ */
310
+ export const ContextAutoCompactionConfigSchema = z.object({
311
+ tokensThreshold: z.number().int().min(CLAUDE_AUTO_COMPACT_TOKENS_MIN).max(CLAUDE_AUTO_COMPACT_TOKENS_MAX).optional(),
312
+ utilizationThreshold: z.number().positive().max(COPILOT_AUTO_COMPACT_UTILIZATION_MAX).optional(),
313
+ });
280
314
  /**
281
315
  * Full agent configuration - persisted to disk in agents.json
282
316
  */
@@ -289,6 +323,8 @@ export const AgentConfigSchema = z.object({
289
323
  persona: z.string().optional(),
290
324
  model: z.string().default(CLAUDE_DEFAULT_MODEL),
291
325
  effort: ReasoningEffortSchema.optional(),
326
+ thinkingConfig: AgentThinkingConfigSchema.optional(),
327
+ contextAutoCompactionConfig: ContextAutoCompactionConfigSchema.optional(),
292
328
  permissionMode: PermissionModeSchema.default(PERMISSION_MODE.DEFAULT),
293
329
  settingSources: z.array(SettingSourceSchema).default([...DEFAULT_SETTING_SOURCES]),
294
330
  settingSourceConfig: SettingSourceConfigSchema.optional(),
@@ -323,6 +359,8 @@ export const CreateAgentInputSchema = z.object({
323
359
  persona: z.string().optional(),
324
360
  model: z.string().optional(),
325
361
  effort: ReasoningEffortSchema.optional(),
362
+ thinkingConfig: AgentThinkingConfigSchema.optional(),
363
+ contextAutoCompactionConfig: ContextAutoCompactionConfigSchema.optional(),
326
364
  permissionMode: PermissionModeSchema.optional(),
327
365
  settingSources: z.array(SettingSourceSchema).optional(),
328
366
  settingSourceConfig: SettingSourceConfigInputSchema.optional(),
@@ -346,8 +384,9 @@ export const UpdateAgentInputSchema = z.object({
346
384
  workspace: z.string().optional(),
347
385
  persona: z.string().optional(),
348
386
  model: z.string().optional(),
349
- // null explicitly clears the effort (back to provider default); undefined leaves it unchanged.
350
387
  effort: ReasoningEffortSchema.nullish(),
388
+ thinkingConfig: AgentThinkingConfigSchema.nullish(),
389
+ contextAutoCompactionConfig: ContextAutoCompactionConfigSchema.nullish(),
351
390
  permissionMode: PermissionModeSchema.optional(),
352
391
  settingSources: z.array(SettingSourceSchema).optional(),
353
392
  settingSourceConfig: SettingSourceConfigInputSchema.optional(),
@@ -370,6 +409,8 @@ export const AgentConfigTemplateSchema = AgentConfigSchema.pick({
370
409
  persona: true,
371
410
  model: true,
372
411
  effort: true,
412
+ thinkingConfig: true,
413
+ contextAutoCompactionConfig: true,
373
414
  permissionMode: true,
374
415
  settingSources: true,
375
416
  availableTools: true,
@@ -49,11 +49,32 @@ export const ArtifactMetadataSchema = z.object({
49
49
  createdBy: AgentTaskSourceSchema,
50
50
  });
51
51
  /**
52
- * Request body for updating an artifact's tags. Applies a remove-then-add delta to the
53
- * current tag set; at least one of addTags/removeTags must be non-empty.
52
+ * Request body for a PATCH artifact update. Tag changes apply a remove-then-add delta to the current
53
+ * set; `content` replaces the raw text. `expectedUpdatedTimestamp` guards against clobbering a
54
+ * concurrent edit — the update is rejected with a conflict when it no longer matches the stored
55
+ * timestamp. At least one of addTags/removeTags/content must be present, and a content replacement
56
+ * must carry the expected timestamp.
54
57
  */
55
- export const ArtifactTagsUpdateSchema = z.object({
58
+ export const ArtifactUpdateSchema = z
59
+ .object({
56
60
  addTags: z.array(z.string()).optional(),
57
61
  removeTags: z.array(z.string()).optional(),
62
+ content: z.string().optional(),
63
+ expectedUpdatedTimestamp: z.number().optional(),
64
+ })
65
+ .superRefine((update, ctx) => {
66
+ if ((update.addTags?.length ?? 0) === 0 && (update.removeTags?.length ?? 0) === 0 && update.content === undefined) {
67
+ ctx.addIssue({
68
+ code: "custom",
69
+ message: "At least one of addTags, removeTags, or content is required",
70
+ });
71
+ }
72
+ if (update.content !== undefined && update.expectedUpdatedTimestamp === undefined) {
73
+ ctx.addIssue({
74
+ code: "custom",
75
+ message: "expectedUpdatedTimestamp is required when content is provided",
76
+ path: ["expectedUpdatedTimestamp"],
77
+ });
78
+ }
58
79
  });
59
80
  //# sourceMappingURL=artifact.schema.js.map
@@ -1,4 +1,4 @@
1
- import { CLAUDE_MODELS } from "../schemas/agent.schema.js";
1
+ import { CLAUDE_CODE_MODEL_OPTIONS, CLAUDE_MODELS, } from "../schemas/agent.schema.js";
2
2
  /**
3
3
  * Maps retired model IDs to their successor.
4
4
  */
@@ -12,4 +12,9 @@ export const COPILOT_MODEL_ALIASES = {};
12
12
  export function resolveModel(model) {
13
13
  return MODEL_ALIASES[model] ?? COPILOT_MODEL_ALIASES[model] ?? model;
14
14
  }
15
+ /** Whether a Claude model supports adaptive thinking, resolving retired IDs to their successor. */
16
+ export function modelSupportsAdaptiveThinking(model) {
17
+ const resolved = resolveModel(model);
18
+ return CLAUDE_CODE_MODEL_OPTIONS.find((option) => option.value === resolved)?.supportsAdaptiveThinking ?? false;
19
+ }
15
20
  //# sourceMappingURL=resolve-model.js.map
@@ -1,6 +1,6 @@
1
1
  import { z } from "zod";
2
2
  import { RequestError } from "../../core/error/request-error.js";
3
- import { GOOGLE_SERVICE_NAME } from "../../services/google/google-client.types.js";
3
+ import { EMAIL_BODY_FORMAT, GOOGLE_SERVICE_NAME } from "../../services/google/google-client.types.js";
4
4
  import { getErrorToolResult, textToolResult } from "../tool-utils.js";
5
5
  export const CREATE_GMAIL_DRAFT_TOOL_NAME = "create_gmail_draft";
6
6
  export function getCreateGmailDraftToolConfig(googleClient) {
@@ -20,7 +20,11 @@ export function getCreateGmailDraftToolConfig(googleClient) {
20
20
  cc: z.array(z.string()).optional().describe("New-draft mode: optional Cc recipients."),
21
21
  bcc: z.array(z.string()).optional().describe("New-draft mode: optional Bcc recipients."),
22
22
  subject: z.string().optional().describe("New-draft mode: subject line. Required without parentMessageId."),
23
- body: z.string().min(1).describe("Draft body in markdown."),
23
+ body: z.string().min(1).describe('Draft body. Defaults to markdown; pass raw HTML when bodyFormat is "html".'),
24
+ bodyFormat: z
25
+ .enum([EMAIL_BODY_FORMAT.MARKDOWN, EMAIL_BODY_FORMAT.HTML])
26
+ .optional()
27
+ .describe('Body format. Defaults to "markdown"; set to "html" to supply raw HTML.'),
24
28
  };
25
29
  const handler = async (args) => {
26
30
  try {
@@ -28,6 +32,7 @@ export function getCreateGmailDraftToolConfig(googleClient) {
28
32
  const result = await googleClient.createGmailReplyDraft({
29
33
  parentMessageId: args.parentMessageId,
30
34
  body: args.body,
35
+ bodyFormat: args.bodyFormat,
31
36
  replyAll: args.replyAll,
32
37
  });
33
38
  return textToolResult([
@@ -46,6 +51,7 @@ export function getCreateGmailDraftToolConfig(googleClient) {
46
51
  bcc: args.bcc,
47
52
  subject: args.subject,
48
53
  body: args.body,
54
+ bodyFormat: args.bodyFormat,
49
55
  });
50
56
  return textToolResult([
51
57
  "Draft created.",
@@ -60,7 +66,7 @@ export function getCreateGmailDraftToolConfig(googleClient) {
60
66
  };
61
67
  const config = {
62
68
  name: CREATE_GMAIL_DRAFT_TOOL_NAME,
63
- description: "Create a draft email in the Drafts folder. Two modes: new draft or reply draft (parentMessageId required, recipients/subject/threading derived from parent, replyAll optional). Body is markdown.",
69
+ description: 'Create a draft email in the Drafts folder. Two modes: new draft or reply draft (parentMessageId required, recipients/subject/threading derived from parent, replyAll optional). Body defaults to markdown; set bodyFormat to "html" to supply raw HTML.',
64
70
  inputSchema,
65
71
  handler,
66
72
  };
@@ -1,4 +1,5 @@
1
1
  import { z } from "zod";
2
+ import { EMAIL_BODY_FORMAT } from "../../services/google/google-client.types.js";
2
3
  import { getErrorToolResult, textToolResult } from "../tool-utils.js";
3
4
  export const REPLY_TO_GMAIL_MESSAGE_TOOL_NAME = "reply_to_gmail_message";
4
5
  export function getReplyToGmailMessageToolConfig(googleClient) {
@@ -6,10 +7,11 @@ export function getReplyToGmailMessageToolConfig(googleClient) {
6
7
  messageId: z
7
8
  .string()
8
9
  .describe("ID of the message being replied to (from list_gmail_messages or get_gmail_thread). Recipients, subject, and threading headers are derived from this parent."),
9
- body: z
10
- .string()
11
- .min(1)
12
- .describe("Reply body in markdown. Recipients will receive both a plain-text version (the markdown source) and an HTML version (rendered)."),
10
+ body: z.string().min(1).describe('Reply body. Defaults to markdown; pass raw HTML when bodyFormat is "html".'),
11
+ bodyFormat: z
12
+ .enum([EMAIL_BODY_FORMAT.MARKDOWN, EMAIL_BODY_FORMAT.HTML])
13
+ .optional()
14
+ .describe('Body format. Defaults to "markdown"; set to "html" to supply raw HTML.'),
13
15
  replyAll: z
14
16
  .boolean()
15
17
  .optional()
@@ -20,6 +22,7 @@ export function getReplyToGmailMessageToolConfig(googleClient) {
20
22
  const result = await googleClient.replyToGmailMessage({
21
23
  parentMessageId: args.messageId,
22
24
  body: args.body,
25
+ bodyFormat: args.bodyFormat,
23
26
  replyAll: args.replyAll,
24
27
  });
25
28
  return textToolResult(["Reply sent.", `Message ID: ${result.id}`, `Thread ID: ${result.threadId}`]);
@@ -30,7 +33,7 @@ export function getReplyToGmailMessageToolConfig(googleClient) {
30
33
  };
31
34
  const config = {
32
35
  name: REPLY_TO_GMAIL_MESSAGE_TOOL_NAME,
33
- description: "Reply to a Gmail message by ID. Recipients (To/Cc), subject (Re: prefix), and threading headers (In-Reply-To, References, threadId) are all derived from the parent - you only supply the body and an optional replyAll flag. Body is markdown; sent as multipart/alternative.",
36
+ description: 'Reply to a Gmail message by ID. Recipients (To/Cc), subject (Re: prefix), and threading headers (In-Reply-To, References, threadId) are all derived from the parent - you only supply the body and an optional replyAll flag. Body defaults to markdown; set bodyFormat to "html" to supply raw HTML.',
34
37
  inputSchema,
35
38
  handler,
36
39
  };
@@ -1,4 +1,5 @@
1
1
  import { z } from "zod";
2
+ import { EMAIL_BODY_FORMAT } from "../../services/google/google-client.types.js";
2
3
  import { getErrorToolResult, textToolResult } from "../tool-utils.js";
3
4
  export const SEND_GMAIL_MESSAGE_TOOL_NAME = "send_gmail_message";
4
5
  export function getSendGmailMessageToolConfig(googleClient) {
@@ -10,10 +11,11 @@ export function getSendGmailMessageToolConfig(googleClient) {
10
11
  cc: z.array(z.string()).optional().describe("Optional Cc recipients (same address format as 'to')."),
11
12
  bcc: z.array(z.string()).optional().describe("Optional Bcc recipients (same address format as 'to')."),
12
13
  subject: z.string().min(1).describe("Email subject line."),
13
- body: z
14
- .string()
15
- .min(1)
16
- .describe("Email body in markdown. Recipients will receive both a plain-text version (the markdown source) and an HTML version (rendered)."),
14
+ body: z.string().min(1).describe('Email body. Defaults to markdown; pass raw HTML when bodyFormat is "html".'),
15
+ bodyFormat: z
16
+ .enum([EMAIL_BODY_FORMAT.MARKDOWN, EMAIL_BODY_FORMAT.HTML])
17
+ .optional()
18
+ .describe('Body format. Defaults to "markdown"; set to "html" to supply raw HTML.'),
17
19
  };
18
20
  const handler = async (args) => {
19
21
  try {
@@ -23,6 +25,7 @@ export function getSendGmailMessageToolConfig(googleClient) {
23
25
  bcc: args.bcc,
24
26
  subject: args.subject,
25
27
  body: args.body,
28
+ bodyFormat: args.bodyFormat,
26
29
  });
27
30
  return textToolResult(["Message sent.", `Message ID: ${result.id}`, `Thread ID: ${result.threadId}`]);
28
31
  }
@@ -32,7 +35,7 @@ export function getSendGmailMessageToolConfig(googleClient) {
32
35
  };
33
36
  const config = {
34
37
  name: SEND_GMAIL_MESSAGE_TOOL_NAME,
35
- description: "Send a new email via the connected Google account. Body is provided as markdown and delivered as multipart/alternative (text/plain + text/html). For replies, use reply_to_gmail_message instead so threading headers are set correctly.",
38
+ description: 'Send a new email via the connected Google account. Body defaults to markdown; set bodyFormat to "html" to supply raw HTML. For replies, use reply_to_gmail_message instead so threading headers are set correctly.',
36
39
  inputSchema,
37
40
  handler,
38
41
  };
@@ -1,4 +1,5 @@
1
1
  import { z } from "zod";
2
+ import { EMAIL_BODY_FORMAT } from "../../services/google/google-client.types.js";
2
3
  import { getErrorToolResult, textToolResult } from "../tool-utils.js";
3
4
  export const UPDATE_GMAIL_DRAFT_TOOL_NAME = "update_gmail_draft";
4
5
  export function getUpdateGmailDraftToolConfig(googleClient) {
@@ -8,7 +9,14 @@ export function getUpdateGmailDraftToolConfig(googleClient) {
8
9
  cc: z.array(z.string()).optional().describe("Replaces Cc; preserved if omitted."),
9
10
  bcc: z.array(z.string()).optional().describe("Replaces Bcc; preserved if omitted."),
10
11
  subject: z.string().optional().describe("Replaces subject; preserved if omitted."),
11
- body: z.string().optional().describe("Markdown. Replaces body; preserved if omitted."),
12
+ body: z
13
+ .string()
14
+ .optional()
15
+ .describe('Replaces body; preserved if omitted. Defaults to markdown; pass raw HTML when bodyFormat is "html".'),
16
+ bodyFormat: z
17
+ .enum([EMAIL_BODY_FORMAT.MARKDOWN, EMAIL_BODY_FORMAT.HTML])
18
+ .optional()
19
+ .describe('Body format for `body`; only meaningful when body is also provided. Defaults to "markdown"; set to "html" to supply raw HTML.'),
12
20
  };
13
21
  const handler = async (args) => {
14
22
  try {
@@ -19,6 +27,7 @@ export function getUpdateGmailDraftToolConfig(googleClient) {
19
27
  bcc: args.bcc,
20
28
  subject: args.subject,
21
29
  body: args.body,
30
+ bodyFormat: args.bodyFormat,
22
31
  });
23
32
  return textToolResult([
24
33
  "Draft updated.",