illuma-agents 1.0.41 → 1.0.43

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.
@@ -0,0 +1,104 @@
1
+ import { DynamicStructuredTool } from '@langchain/core/tools';
2
+ /**
3
+ * Desktop tool names - keep in sync with Ranger Desktop Electron app
4
+ * These tools execute locally in the Electron app, NOT on the server
5
+ */
6
+ export declare const EDesktopTools: {
7
+ readonly SCREENSHOT: "computer_screenshot";
8
+ readonly CLICK: "computer_click";
9
+ readonly DOUBLE_CLICK: "computer_double_click";
10
+ readonly RIGHT_CLICK: "computer_right_click";
11
+ readonly TYPE: "computer_type";
12
+ readonly KEY: "computer_key";
13
+ readonly KEY_COMBO: "computer_key_combo";
14
+ readonly SCROLL: "computer_scroll";
15
+ readonly DRAG: "computer_drag";
16
+ readonly GET_ACTIVE_WINDOW: "computer_get_active_window";
17
+ readonly GET_MOUSE_POSITION: "computer_get_mouse_position";
18
+ readonly CLIPBOARD_READ: "clipboard_read";
19
+ readonly CLIPBOARD_WRITE: "clipboard_write";
20
+ readonly CLIPBOARD_PASTE: "clipboard_paste";
21
+ readonly WAIT: "computer_wait";
22
+ };
23
+ export type DesktopToolName = (typeof EDesktopTools)[keyof typeof EDesktopTools];
24
+ /**
25
+ * Callback function type for waiting on desktop action results
26
+ * This allows the server (Ranger) to provide a callback that waits for the Electron app
27
+ * to POST results back to the server before returning to the LLM.
28
+ *
29
+ * @param action - The desktop action (click, type, screenshot, etc.)
30
+ * @param args - Arguments for the action
31
+ * @param toolCallId - Unique ID for this tool call (from config.toolCall.id)
32
+ * @returns Promise that resolves with the actual desktop result
33
+ */
34
+ export type DesktopToolCallback = (action: string, args: Record<string, unknown>, toolCallId: string) => Promise<DesktopActionResult>;
35
+ /**
36
+ * Result returned from desktop action execution
37
+ */
38
+ export interface DesktopActionResult {
39
+ success: boolean;
40
+ error?: string;
41
+ screenshot?: {
42
+ base64: string;
43
+ width: number;
44
+ height: number;
45
+ };
46
+ activeWindow?: {
47
+ title: string;
48
+ app: string;
49
+ bounds?: {
50
+ x: number;
51
+ y: number;
52
+ width: number;
53
+ height: number;
54
+ };
55
+ };
56
+ mousePosition?: {
57
+ x: number;
58
+ y: number;
59
+ };
60
+ clipboard?: string;
61
+ }
62
+ /**
63
+ * Check if desktop capability is available based on request headers or context
64
+ * The Ranger Desktop Electron app sets these headers when connected:
65
+ * - X-Ranger-Desktop: true
66
+ * - X-Ranger-Desktop-Capable: true
67
+ */
68
+ export declare function hasDesktopCapability(req?: {
69
+ headers?: Record<string, string | string[] | undefined>;
70
+ }): boolean;
71
+ /**
72
+ * Desktop tool response interface
73
+ * This is what the Electron app returns after executing the action
74
+ */
75
+ export interface DesktopToolResponse {
76
+ requiresDesktopExecution: true;
77
+ action: string;
78
+ args: Record<string, unknown>;
79
+ toolCallId?: string;
80
+ }
81
+ /**
82
+ * Options for creating desktop tools
83
+ */
84
+ export interface CreateDesktopToolsOptions {
85
+ /**
86
+ * Optional callback that waits for desktop action results.
87
+ * When provided, tools will await this callback to get actual results from the Electron app.
88
+ * When not provided, tools return markers immediately (for non-server contexts).
89
+ */
90
+ waitForResult?: DesktopToolCallback;
91
+ }
92
+ /**
93
+ * Create desktop automation tools for the agent
94
+ * These tools allow AI to control the user's desktop when Ranger Desktop is running
95
+ */
96
+ export declare function createDesktopTools(options?: CreateDesktopToolsOptions): DynamicStructuredTool[];
97
+ /**
98
+ * Get all desktop tool names
99
+ */
100
+ export declare function getDesktopToolNames(): DesktopToolName[];
101
+ /**
102
+ * Check if a tool name is a desktop tool
103
+ */
104
+ export declare function isDesktopTool(name: string): name is DesktopToolName;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "illuma-agents",
3
- "version": "1.0.41",
3
+ "version": "1.0.43",
4
4
  "main": "./dist/cjs/main.cjs",
5
5
  "module": "./dist/esm/main.mjs",
6
6
  "types": "./dist/types/index.d.ts",
@@ -1071,9 +1071,31 @@ export class StandardGraph extends Graph<t.BaseGraphState, t.GraphNode> {
1071
1071
  try {
1072
1072
  // Use structured output invocation (non-streaming)
1073
1073
  // Get a fresh model WITHOUT tools bound - bindTools() returns RunnableBinding which lacks withStructuredOutput
1074
+ // Also disable thinking mode - Anthropic/Bedrock doesn't allow tool_choice with thinking enabled
1075
+ const structuredClientOptions = { ...agentContext.clientOptions } as t.ClientOptions;
1076
+
1077
+ // Remove thinking configuration for Bedrock
1078
+ if (agentContext.provider === Providers.BEDROCK) {
1079
+ const bedrockOpts = structuredClientOptions as t.BedrockAnthropicClientOptions;
1080
+ if (bedrockOpts.additionalModelRequestFields?.['thinking']) {
1081
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
1082
+ const additionalFields = Object.assign({}, bedrockOpts.additionalModelRequestFields) as any;
1083
+ delete additionalFields.thinking;
1084
+ bedrockOpts.additionalModelRequestFields = additionalFields;
1085
+ }
1086
+ }
1087
+
1088
+ // Remove thinking configuration for Anthropic
1089
+ if (agentContext.provider === Providers.ANTHROPIC) {
1090
+ const anthropicOpts = structuredClientOptions as t.AnthropicClientOptions;
1091
+ if (anthropicOpts.thinking) {
1092
+ delete anthropicOpts.thinking;
1093
+ }
1094
+ }
1095
+
1074
1096
  const structuredModel = this.getNewModel({
1075
1097
  provider: agentContext.provider,
1076
- clientOptions: agentContext.clientOptions,
1098
+ clientOptions: structuredClientOptions,
1077
1099
  });
1078
1100
 
1079
1101
  const { structuredResponse, rawMessage } =
package/src/index.ts CHANGED
@@ -12,6 +12,7 @@ export * from './graphs';
12
12
  export * from './tools/Calculator';
13
13
  export * from './tools/CodeExecutor';
14
14
  export * from './tools/BrowserTools';
15
+ export * from './tools/DesktopTools';
15
16
  export * from './tools/ProgrammaticToolCalling';
16
17
  export * from './tools/ToolSearch';
17
18
  export * from './tools/handlers';
package/src/stream.ts CHANGED
@@ -737,6 +737,23 @@ export function createContentAggregator(): t.ContentAggregatorResult {
737
737
  };
738
738
 
739
739
  updateContent(runStep.index, contentPart, true);
740
+ } else if (event === GraphEvents.ON_STRUCTURED_OUTPUT) {
741
+ // Handle structured output as text content with formatted JSON
742
+ const structuredData = data as unknown as {
743
+ structuredResponse: Record<string, unknown>;
744
+ schema: Record<string, unknown>;
745
+ };
746
+
747
+ if (structuredData.structuredResponse) {
748
+ const jsonText = JSON.stringify(structuredData.structuredResponse, null, 2);
749
+ const contentPart: t.MessageContentComplex = {
750
+ type: ContentTypes.TEXT,
751
+ text: jsonText,
752
+ };
753
+ // Add at index 0 or next available
754
+ const nextIndex = contentParts.length;
755
+ updateContent(nextIndex, contentPart);
756
+ }
740
757
  }
741
758
  };
742
759