@sayknow-cli/coding-agent 0.3.2 → 0.3.4
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/dist/types/config/model-profiles.d.ts +2 -2
- package/dist/types/config/model-registry.d.ts +3 -3
- package/dist/types/config/models-config-schema.d.ts +0 -5
- package/dist/types/config/settings-schema.d.ts +78 -9
- package/dist/types/export/html/template.generated.d.ts +1 -1
- package/dist/types/skc-runtime/state-renderer.d.ts +5 -0
- package/dist/types/skc-runtime/ultragoal-guard.d.ts +37 -1
- package/dist/types/skc-runtime/ultragoal-runtime.d.ts +80 -0
- package/dist/types/tools/browser/tab-supervisor.d.ts +31 -0
- package/dist/types/tools/computer-gc.d.ts +23 -0
- package/dist/types/tools/cron.d.ts +36 -61
- package/dist/types/tools/index.d.ts +0 -1
- package/dist/types/tools/resource-gc.d.ts +54 -0
- package/dist/types/web/search/index.d.ts +1 -0
- package/dist/types/web/search/providers/utils.d.ts +11 -4
- package/package.json +7 -7
- package/src/cli/args.ts +0 -1
- package/src/cli/fast-help.ts +0 -1
- package/src/cli/plugin-cli.ts +1 -1
- package/src/cli/web-search-cli.ts +5 -0
- package/src/config/model-profile-activation.ts +7 -1
- package/src/config/model-profiles.ts +3 -4
- package/src/config/model-registry.ts +3 -6
- package/src/config/models-config-schema.ts +1 -1
- package/src/config/settings-schema.ts +80 -10
- package/src/export/html/template.generated.ts +1 -1
- package/src/export/html/template.js +0 -12
- package/src/goals/tools/goal-tool.ts +14 -1
- package/src/internal-urls/docs-index.generated.ts +3 -4
- package/src/modes/components/model-selector.ts +9 -1
- package/src/modes/controllers/selector-controller.ts +6 -0
- package/src/prompts/system/system-prompt.md +2 -2
- package/src/prompts/tools/cron.md +5 -3
- package/src/prompts/tools/read.md +1 -1
- package/src/sdk.ts +5 -0
- package/src/session/agent-session.ts +44 -0
- package/src/skc-runtime/state-renderer.ts +13 -0
- package/src/skc-runtime/ultragoal-guard.ts +167 -0
- package/src/skc-runtime/ultragoal-runtime.ts +221 -1
- package/src/tools/browser/tab-supervisor.ts +86 -2
- package/src/tools/computer-gc.ts +66 -0
- package/src/tools/computer.ts +2 -0
- package/src/tools/cron.ts +75 -112
- package/src/tools/index.ts +2 -8
- package/src/tools/read.ts +25 -55
- package/src/tools/renderers.ts +0 -2
- package/src/tools/resource-gc.ts +291 -0
- package/src/tools/ultragoal-ask-guard.ts +7 -1
- package/src/web/search/index.ts +1 -0
- package/src/web/search/providers/utils.ts +22 -5
- package/vendor/insane-search/MANIFEST.json +3 -1
- package/vendor/insane-search/engine/__init__.py +14 -0
- package/vendor/insane-search/engine/content_safety.py +151 -0
- package/vendor/insane-search/engine/fetch_chain.py +32 -0
- package/vendor/insane-search/engine/tests/test_u8.py +216 -0
- package/dist/types/tools/inspect-image-renderer.d.ts +0 -26
- package/dist/types/tools/inspect-image.d.ts +0 -31
- package/src/prompts/tools/inspect-image-system.md +0 -20
- package/src/prompts/tools/inspect-image.md +0 -32
- package/src/tools/inspect-image-renderer.ts +0 -103
- package/src/tools/inspect-image.ts +0 -172
package/src/tools/cron.ts
CHANGED
|
@@ -19,34 +19,36 @@ const MAX_RECURRING_JITTER_MS = 30 * 60 * 1000;
|
|
|
19
19
|
const MAX_ONE_SHOT_EARLY_JITTER_MS = 90 * 1000;
|
|
20
20
|
const MAX_TIMEOUT_MS = 2_147_483_647;
|
|
21
21
|
|
|
22
|
-
const
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
})
|
|
49
|
-
|
|
22
|
+
const cronSchema = z
|
|
23
|
+
.object({
|
|
24
|
+
op: z
|
|
25
|
+
.enum(["create", "list", "delete"])
|
|
26
|
+
.describe(
|
|
27
|
+
"operation: 'create' schedules a prompt on a cron expression, 'list' enumerates scheduled tasks, 'delete' cancels a task by id",
|
|
28
|
+
),
|
|
29
|
+
cron_expression: z
|
|
30
|
+
.string()
|
|
31
|
+
.optional()
|
|
32
|
+
.describe(
|
|
33
|
+
"(op=create, required) Standard 5-field cron expression in the user's local timezone: 'minute hour day-of-month month day-of-week'. Examples: '*/5 * * * *' (every 5 min), '0 9 * * *' (9am daily), '0 9 * * 1-5' (weekdays at 9am). Day-of-week uses 0/7 for Sunday through 6 for Saturday. When both day-of-month and day-of-week are constrained, a date matches if either field matches (vixie-cron semantics).",
|
|
34
|
+
),
|
|
35
|
+
prompt: z
|
|
36
|
+
.string()
|
|
37
|
+
.optional()
|
|
38
|
+
.describe(
|
|
39
|
+
"(op=create, required) Prompt to inject between turns when the cron fires. May reference slash commands (e.g. '/review-pr 1234') or natural-language instructions.",
|
|
40
|
+
),
|
|
41
|
+
recurring: z
|
|
42
|
+
.boolean()
|
|
43
|
+
.optional()
|
|
44
|
+
.describe(
|
|
45
|
+
"(op=create) true to fire on every match of the cron expression (recurring, auto-expires after 7 days); false to fire once at the next match and then self-delete.",
|
|
46
|
+
),
|
|
47
|
+
id: z.string().optional().describe("(op=delete, required) The 8-character job ID returned by op=create."),
|
|
48
|
+
})
|
|
49
|
+
.strict();
|
|
50
|
+
|
|
51
|
+
export type CronParams = z.infer<typeof cronSchema>;
|
|
50
52
|
|
|
51
53
|
export interface CronJobSnapshot {
|
|
52
54
|
id: string;
|
|
@@ -68,20 +70,14 @@ export interface CronListJobDetails {
|
|
|
68
70
|
humanSchedule: string;
|
|
69
71
|
}
|
|
70
72
|
|
|
71
|
-
export interface
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
73
|
+
export interface CronToolDetails {
|
|
74
|
+
op: "create" | "list" | "delete";
|
|
75
|
+
id?: string;
|
|
76
|
+
cron_expression?: string;
|
|
77
|
+
recurring?: boolean;
|
|
75
78
|
nextFireAt?: number;
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
export interface CronListToolDetails {
|
|
79
|
-
jobs: CronListJobDetails[];
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
export interface CronDeleteToolDetails {
|
|
83
|
-
id: string;
|
|
84
|
-
deleted: boolean;
|
|
79
|
+
jobs?: CronListJobDetails[];
|
|
80
|
+
deleted?: boolean;
|
|
85
81
|
}
|
|
86
82
|
|
|
87
83
|
interface CronTimerHandle {
|
|
@@ -543,12 +539,12 @@ function isCronDisabled(): boolean {
|
|
|
543
539
|
return process.env.CLAUDE_CODE_DISABLE_CRON === "1";
|
|
544
540
|
}
|
|
545
541
|
|
|
546
|
-
export class
|
|
547
|
-
readonly name = "
|
|
548
|
-
readonly label = "
|
|
549
|
-
readonly summary = "Schedule
|
|
542
|
+
export class CronTool implements AgentTool<typeof cronSchema, CronToolDetails> {
|
|
543
|
+
readonly name = "cron";
|
|
544
|
+
readonly label = "Cron";
|
|
545
|
+
readonly summary = "Schedule, list, and cancel cron-style prompts (op: create | list | delete)";
|
|
550
546
|
readonly description: string;
|
|
551
|
-
readonly parameters =
|
|
547
|
+
readonly parameters = cronSchema;
|
|
552
548
|
readonly strict = true;
|
|
553
549
|
readonly loadMode = "discoverable";
|
|
554
550
|
|
|
@@ -556,19 +552,30 @@ export class CronCreateTool implements AgentTool<typeof cronCreateSchema, CronCr
|
|
|
556
552
|
this.description = prompt.render(cronDescription);
|
|
557
553
|
}
|
|
558
554
|
|
|
559
|
-
static createIf(session: ToolSession):
|
|
555
|
+
static createIf(session: ToolSession): CronTool | null {
|
|
560
556
|
if (!isBackgroundJobSupportEnabled(session.settings)) return null;
|
|
561
557
|
if (isCronDisabled()) return null;
|
|
562
|
-
return new
|
|
558
|
+
return new CronTool(session);
|
|
563
559
|
}
|
|
564
560
|
|
|
565
561
|
async execute(
|
|
566
562
|
_toolCallId: string,
|
|
567
|
-
params:
|
|
563
|
+
params: CronParams,
|
|
568
564
|
_signal?: AbortSignal,
|
|
569
|
-
_onUpdate?: AgentToolUpdateCallback<
|
|
565
|
+
_onUpdate?: AgentToolUpdateCallback<CronToolDetails>,
|
|
570
566
|
_context?: AgentToolContext,
|
|
571
|
-
): Promise<AgentToolResult<
|
|
567
|
+
): Promise<AgentToolResult<CronToolDetails>> {
|
|
568
|
+
switch (params.op) {
|
|
569
|
+
case "create":
|
|
570
|
+
return this.#create(params);
|
|
571
|
+
case "list":
|
|
572
|
+
return this.#list();
|
|
573
|
+
case "delete":
|
|
574
|
+
return this.#delete(params);
|
|
575
|
+
}
|
|
576
|
+
}
|
|
577
|
+
|
|
578
|
+
async #create(params: CronParams): Promise<AgentToolResult<CronToolDetails>> {
|
|
572
579
|
const manager = AsyncJobManager.instance();
|
|
573
580
|
if (!manager) {
|
|
574
581
|
throw new ToolError("Async execution is disabled; cron is unavailable in this session.");
|
|
@@ -576,26 +583,30 @@ export class CronCreateTool implements AgentTool<typeof cronCreateSchema, CronCr
|
|
|
576
583
|
if (isCronDisabled()) {
|
|
577
584
|
throw new ToolError("Cron is disabled by CLAUDE_CODE_DISABLE_CRON=1.");
|
|
578
585
|
}
|
|
586
|
+
if (!params.cron_expression || !params.prompt) {
|
|
587
|
+
throw new ToolError("cron op=create requires both 'cron_expression' and 'prompt'.");
|
|
588
|
+
}
|
|
579
589
|
validateCronExpression(params.cron_expression);
|
|
580
590
|
|
|
581
591
|
const ownerId = this.session.getAgentId?.() ?? undefined;
|
|
582
592
|
const state = getOrCreateOwnerState(ownerId);
|
|
583
593
|
if (state.jobs.size >= MAX_CRON_TASKS_PER_OWNER) {
|
|
584
594
|
throw new ToolError(
|
|
585
|
-
`Cron task limit reached (${MAX_CRON_TASKS_PER_OWNER}). Cancel an existing task with
|
|
595
|
+
`Cron task limit reached (${MAX_CRON_TASKS_PER_OWNER}). Cancel an existing task with cron op=delete first.`,
|
|
586
596
|
);
|
|
587
597
|
}
|
|
588
598
|
ensureOwnerCleanup(ownerId, manager, state);
|
|
589
599
|
|
|
590
600
|
const id = generateCronId(new Set(state.jobs.keys()));
|
|
591
601
|
const now = Date.now();
|
|
602
|
+
const recurring = params.recurring ?? true;
|
|
592
603
|
const snapshot: CronJobSnapshot = {
|
|
593
604
|
id,
|
|
594
605
|
cron_expression: params.cron_expression.trim(),
|
|
595
606
|
prompt: params.prompt,
|
|
596
|
-
recurring
|
|
607
|
+
recurring,
|
|
597
608
|
createdAt: now,
|
|
598
|
-
expiresAt:
|
|
609
|
+
expiresAt: recurring ? now + CRON_RECURRING_MAX_AGE_MS : undefined,
|
|
599
610
|
humanSchedule: humanizeCronExpression(params.cron_expression.trim()),
|
|
600
611
|
ownerId,
|
|
601
612
|
};
|
|
@@ -604,7 +615,7 @@ export class CronCreateTool implements AgentTool<typeof cronCreateSchema, CronCr
|
|
|
604
615
|
scheduleExpiry(ownerId, record);
|
|
605
616
|
scheduleRecord(ownerId, state, record);
|
|
606
617
|
|
|
607
|
-
logger.debug("
|
|
618
|
+
logger.debug("cron op=create: scheduled task", {
|
|
608
619
|
id,
|
|
609
620
|
ownerId,
|
|
610
621
|
cron: snapshot.cron_expression,
|
|
@@ -614,6 +625,7 @@ export class CronCreateTool implements AgentTool<typeof cronCreateSchema, CronCr
|
|
|
614
625
|
return {
|
|
615
626
|
content: [{ type: "text", text: `Scheduled ${id} (${snapshot.humanSchedule})` }],
|
|
616
627
|
details: {
|
|
628
|
+
op: "create",
|
|
617
629
|
id,
|
|
618
630
|
cron_expression: snapshot.cron_expression,
|
|
619
631
|
recurring: snapshot.recurring,
|
|
@@ -621,34 +633,8 @@ export class CronCreateTool implements AgentTool<typeof cronCreateSchema, CronCr
|
|
|
621
633
|
},
|
|
622
634
|
};
|
|
623
635
|
}
|
|
624
|
-
}
|
|
625
|
-
|
|
626
|
-
export class CronListTool implements AgentTool<typeof cronListSchema, CronListToolDetails> {
|
|
627
|
-
readonly name = "CronList";
|
|
628
|
-
readonly label = "CronList";
|
|
629
|
-
readonly summary = "List scheduled cron jobs";
|
|
630
|
-
readonly description: string;
|
|
631
|
-
readonly parameters = cronListSchema;
|
|
632
|
-
readonly strict = true;
|
|
633
|
-
readonly loadMode = "discoverable";
|
|
634
|
-
|
|
635
|
-
constructor(private readonly session: ToolSession) {
|
|
636
|
-
this.description = prompt.render(cronDescription);
|
|
637
|
-
}
|
|
638
636
|
|
|
639
|
-
|
|
640
|
-
if (!isBackgroundJobSupportEnabled(session.settings)) return null;
|
|
641
|
-
if (isCronDisabled()) return null;
|
|
642
|
-
return new CronListTool(session);
|
|
643
|
-
}
|
|
644
|
-
|
|
645
|
-
async execute(
|
|
646
|
-
_toolCallId: string,
|
|
647
|
-
_params: CronListParams,
|
|
648
|
-
_signal?: AbortSignal,
|
|
649
|
-
_onUpdate?: AgentToolUpdateCallback<CronListToolDetails>,
|
|
650
|
-
_context?: AgentToolContext,
|
|
651
|
-
): Promise<AgentToolResult<CronListToolDetails>> {
|
|
637
|
+
async #list(): Promise<AgentToolResult<CronToolDetails>> {
|
|
652
638
|
const ownerId = this.session.getAgentId?.() ?? undefined;
|
|
653
639
|
const state = schedulesByOwner.get(ownerKey(ownerId));
|
|
654
640
|
const records = state
|
|
@@ -658,7 +644,7 @@ export class CronListTool implements AgentTool<typeof cronListSchema, CronListTo
|
|
|
658
644
|
if (jobs.length === 0) {
|
|
659
645
|
return {
|
|
660
646
|
content: [{ type: "text", text: "No scheduled jobs" }],
|
|
661
|
-
details: { jobs: [] },
|
|
647
|
+
details: { op: "list", jobs: [] },
|
|
662
648
|
};
|
|
663
649
|
}
|
|
664
650
|
const lines = jobs.map(job => {
|
|
@@ -667,43 +653,20 @@ export class CronListTool implements AgentTool<typeof cronListSchema, CronListTo
|
|
|
667
653
|
});
|
|
668
654
|
return {
|
|
669
655
|
content: [{ type: "text", text: lines.join("\n") }],
|
|
670
|
-
details: { jobs },
|
|
656
|
+
details: { op: "list", jobs },
|
|
671
657
|
};
|
|
672
658
|
}
|
|
673
|
-
}
|
|
674
659
|
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
readonly description: string;
|
|
680
|
-
readonly parameters = cronDeleteSchema;
|
|
681
|
-
readonly strict = true;
|
|
682
|
-
readonly loadMode = "discoverable";
|
|
683
|
-
|
|
684
|
-
constructor(private readonly session: ToolSession) {
|
|
685
|
-
this.description = prompt.render(cronDescription);
|
|
686
|
-
}
|
|
687
|
-
|
|
688
|
-
static createIf(session: ToolSession): CronDeleteTool | null {
|
|
689
|
-
if (!isBackgroundJobSupportEnabled(session.settings)) return null;
|
|
690
|
-
if (isCronDisabled()) return null;
|
|
691
|
-
return new CronDeleteTool(session);
|
|
692
|
-
}
|
|
693
|
-
|
|
694
|
-
async execute(
|
|
695
|
-
_toolCallId: string,
|
|
696
|
-
params: CronDeleteParams,
|
|
697
|
-
_signal?: AbortSignal,
|
|
698
|
-
_onUpdate?: AgentToolUpdateCallback<CronDeleteToolDetails>,
|
|
699
|
-
_context?: AgentToolContext,
|
|
700
|
-
): Promise<AgentToolResult<CronDeleteToolDetails>> {
|
|
660
|
+
async #delete(params: CronParams): Promise<AgentToolResult<CronToolDetails>> {
|
|
661
|
+
if (!params.id) {
|
|
662
|
+
throw new ToolError("cron op=delete requires 'id'.");
|
|
663
|
+
}
|
|
701
664
|
const ownerId = this.session.getAgentId?.() ?? undefined;
|
|
702
665
|
const deleted = deleteRecord(ownerId, params.id);
|
|
703
666
|
const text = deleted ? `Cancelled ${params.id}` : `No scheduled task '${params.id}' found; nothing to cancel.`;
|
|
704
667
|
return {
|
|
705
668
|
content: [{ type: "text", text }],
|
|
706
|
-
details: { id: params.id, deleted },
|
|
669
|
+
details: { op: "delete", id: params.id, deleted },
|
|
707
670
|
};
|
|
708
671
|
}
|
|
709
672
|
}
|
package/src/tools/index.ts
CHANGED
|
@@ -38,12 +38,11 @@ import { BrowserTool } from "./browser";
|
|
|
38
38
|
import { CalculatorTool } from "./calculator";
|
|
39
39
|
import { type CheckpointState, CheckpointTool, RewindTool } from "./checkpoint";
|
|
40
40
|
import { ComputerTool, isComputerCallable, isComputerLoadablePlatform } from "./computer";
|
|
41
|
-
import {
|
|
41
|
+
import { CronTool } from "./cron";
|
|
42
42
|
import { DebugTool } from "./debug";
|
|
43
43
|
import { EvalTool } from "./eval";
|
|
44
44
|
import { FindTool } from "./find";
|
|
45
45
|
import { GithubTool } from "./gh";
|
|
46
|
-
import { InspectImageTool } from "./inspect-image";
|
|
47
46
|
import { IrcTool } from "./irc";
|
|
48
47
|
import { JobTool } from "./job";
|
|
49
48
|
import { MonitorTool } from "./monitor";
|
|
@@ -83,7 +82,6 @@ export * from "./eval";
|
|
|
83
82
|
export * from "./find";
|
|
84
83
|
export * from "./gh";
|
|
85
84
|
export * from "./image-gen";
|
|
86
|
-
export * from "./inspect-image";
|
|
87
85
|
export * from "./irc";
|
|
88
86
|
export * from "./job";
|
|
89
87
|
export * from "./monitor";
|
|
@@ -389,7 +387,6 @@ export const BUILTIN_TOOLS: Record<string, ToolFactory> = {
|
|
|
389
387
|
find: s => new FindTool(s),
|
|
390
388
|
search: s => new SearchTool(s),
|
|
391
389
|
lsp: LspTool.createIf,
|
|
392
|
-
inspect_image: s => new InspectImageTool(s),
|
|
393
390
|
browser: s => new BrowserTool(s),
|
|
394
391
|
...(isComputerLoadablePlatform() ? { computer: ComputerTool.createIf } : {}),
|
|
395
392
|
checkpoint: CheckpointTool.createIf,
|
|
@@ -398,9 +395,7 @@ export const BUILTIN_TOOLS: Record<string, ToolFactory> = {
|
|
|
398
395
|
subagent: s => new SubagentTool(s),
|
|
399
396
|
job: JobTool.createIf,
|
|
400
397
|
monitor: MonitorTool.createIf,
|
|
401
|
-
|
|
402
|
-
CronList: CronListTool.createIf,
|
|
403
|
-
CronDelete: CronDeleteTool.createIf,
|
|
398
|
+
cron: CronTool.createIf,
|
|
404
399
|
recipe: RecipeTool.createIf,
|
|
405
400
|
irc: IrcTool.createIf,
|
|
406
401
|
todo_write: s => new TodoWriteTool(s),
|
|
@@ -560,7 +555,6 @@ export async function createTools(session: ToolSession, toolNames?: string[]): P
|
|
|
560
555
|
if (name === "ast_grep") return session.settings.get("astGrep.enabled");
|
|
561
556
|
if (name === "ast_edit") return session.settings.get("astEdit.enabled");
|
|
562
557
|
if (name === "render_mermaid") return session.settings.get("renderMermaid.enabled");
|
|
563
|
-
if (name === "inspect_image") return session.settings.get("inspect_image.enabled");
|
|
564
558
|
if (name === "web_search") return session.settings.get("web_search.enabled");
|
|
565
559
|
// search_tool_bm25 is allowed when either legacy mcp.discoveryMode or new tools.discoveryMode is active.
|
|
566
560
|
if (name === "search_tool_bm25") return discoveryActive;
|
package/src/tools/read.ts
CHANGED
|
@@ -670,7 +670,6 @@ export class ReadTool implements AgentTool<typeof readSchema, ReadToolDetails> {
|
|
|
670
670
|
|
|
671
671
|
readonly #autoResizeImages: boolean;
|
|
672
672
|
readonly #defaultLimit: number;
|
|
673
|
-
readonly #inspectImageEnabled: boolean;
|
|
674
673
|
|
|
675
674
|
constructor(private readonly session: ToolSession) {
|
|
676
675
|
const displayMode = resolveFileDisplayMode(session);
|
|
@@ -679,7 +678,6 @@ export class ReadTool implements AgentTool<typeof readSchema, ReadToolDetails> {
|
|
|
679
678
|
1,
|
|
680
679
|
Math.min(session.settings.get("read.defaultLimit") ?? DEFAULT_MAX_LINES, DEFAULT_MAX_LINES),
|
|
681
680
|
);
|
|
682
|
-
this.#inspectImageEnabled = session.settings.get("inspect_image.enabled");
|
|
683
681
|
this.description = prompt.render(readDescription, {
|
|
684
682
|
DEFAULT_LIMIT: String(this.#defaultLimit),
|
|
685
683
|
DEFAULT_MAX_LINES: String(DEFAULT_MAX_LINES),
|
|
@@ -1572,62 +1570,34 @@ export class ReadTool implements AgentTool<typeof readSchema, ReadToolDetails> {
|
|
|
1572
1570
|
| undefined;
|
|
1573
1571
|
|
|
1574
1572
|
if (mimeType) {
|
|
1575
|
-
if (
|
|
1576
|
-
const
|
|
1577
|
-
const
|
|
1578
|
-
|
|
1579
|
-
|
|
1580
|
-
|
|
1581
|
-
|
|
1582
|
-
|
|
1583
|
-
|
|
1584
|
-
|
|
1585
|
-
|
|
1586
|
-
|
|
1587
|
-
|
|
1588
|
-
|
|
1589
|
-
|
|
1590
|
-
|
|
1591
|
-
|
|
1592
|
-
|
|
1593
|
-
|
|
1594
|
-
|
|
1595
|
-
this.session.cwd,
|
|
1596
|
-
)}" and a question describing what to inspect and the desired output format.`,
|
|
1573
|
+
if (fileSize > MAX_IMAGE_SIZE) {
|
|
1574
|
+
const sizeStr = formatBytes(fileSize);
|
|
1575
|
+
const maxStr = formatBytes(MAX_IMAGE_SIZE);
|
|
1576
|
+
throw new ToolError(`Image file too large: ${sizeStr} exceeds ${maxStr} limit.`);
|
|
1577
|
+
}
|
|
1578
|
+
try {
|
|
1579
|
+
const imageInput = await loadImageInput({
|
|
1580
|
+
path: readPath,
|
|
1581
|
+
cwd: this.session.cwd,
|
|
1582
|
+
autoResize: this.#autoResizeImages,
|
|
1583
|
+
maxBytes: MAX_IMAGE_SIZE,
|
|
1584
|
+
resolvedPath: absolutePath,
|
|
1585
|
+
detectedMimeType: mimeType,
|
|
1586
|
+
});
|
|
1587
|
+
if (!imageInput) {
|
|
1588
|
+
throw new ToolError(`Read image file [${mimeType}] failed: unsupported image format.`);
|
|
1589
|
+
}
|
|
1590
|
+
content = [
|
|
1591
|
+
{ type: "text", text: imageInput.textNote },
|
|
1592
|
+
{ type: "image", data: imageInput.data, mimeType: imageInput.mimeType },
|
|
1597
1593
|
];
|
|
1598
|
-
content = [{ type: "text", text: metadataLines.join("\n") }];
|
|
1599
1594
|
details = {};
|
|
1600
|
-
sourcePath =
|
|
1601
|
-
}
|
|
1602
|
-
if (
|
|
1603
|
-
|
|
1604
|
-
const maxStr = formatBytes(MAX_IMAGE_SIZE);
|
|
1605
|
-
throw new ToolError(`Image file too large: ${sizeStr} exceeds ${maxStr} limit.`);
|
|
1606
|
-
}
|
|
1607
|
-
try {
|
|
1608
|
-
const imageInput = await loadImageInput({
|
|
1609
|
-
path: readPath,
|
|
1610
|
-
cwd: this.session.cwd,
|
|
1611
|
-
autoResize: this.#autoResizeImages,
|
|
1612
|
-
maxBytes: MAX_IMAGE_SIZE,
|
|
1613
|
-
resolvedPath: absolutePath,
|
|
1614
|
-
detectedMimeType: mimeType,
|
|
1615
|
-
});
|
|
1616
|
-
if (!imageInput) {
|
|
1617
|
-
throw new ToolError(`Read image file [${mimeType}] failed: unsupported image format.`);
|
|
1618
|
-
}
|
|
1619
|
-
content = [
|
|
1620
|
-
{ type: "text", text: imageInput.textNote },
|
|
1621
|
-
{ type: "image", data: imageInput.data, mimeType: imageInput.mimeType },
|
|
1622
|
-
];
|
|
1623
|
-
details = {};
|
|
1624
|
-
sourcePath = imageInput.resolvedPath;
|
|
1625
|
-
} catch (error) {
|
|
1626
|
-
if (error instanceof ImageInputTooLargeError) {
|
|
1627
|
-
throw new ToolError(error.message);
|
|
1628
|
-
}
|
|
1629
|
-
throw error;
|
|
1595
|
+
sourcePath = imageInput.resolvedPath;
|
|
1596
|
+
} catch (error) {
|
|
1597
|
+
if (error instanceof ImageInputTooLargeError) {
|
|
1598
|
+
throw new ToolError(error.message);
|
|
1630
1599
|
}
|
|
1600
|
+
throw error;
|
|
1631
1601
|
}
|
|
1632
1602
|
} else if (isNotebookPath(absolutePath) && !isRawSelector(parsed)) {
|
|
1633
1603
|
const notebookText = await readEditableNotebookText(absolutePath, localReadPath);
|
package/src/tools/renderers.ts
CHANGED
|
@@ -22,7 +22,6 @@ import { debugToolRenderer } from "./debug";
|
|
|
22
22
|
import { evalToolRenderer } from "./eval";
|
|
23
23
|
import { findToolRenderer } from "./find";
|
|
24
24
|
import { githubToolRenderer } from "./gh-renderer";
|
|
25
|
-
import { inspectImageToolRenderer } from "./inspect-image-renderer";
|
|
26
25
|
import { jobToolRenderer } from "./job";
|
|
27
26
|
import { readToolRenderer } from "./read";
|
|
28
27
|
import { recipeToolRenderer } from "./recipe/render";
|
|
@@ -63,7 +62,6 @@ export const toolRenderers: Record<string, ToolRenderer> = {
|
|
|
63
62
|
find: findToolRenderer as ToolRenderer,
|
|
64
63
|
search: searchToolRenderer as ToolRenderer,
|
|
65
64
|
lsp: lspToolRenderer as ToolRenderer,
|
|
66
|
-
inspect_image: inspectImageToolRenderer as ToolRenderer,
|
|
67
65
|
read: readToolRenderer as ToolRenderer,
|
|
68
66
|
job: jobToolRenderer as ToolRenderer,
|
|
69
67
|
resolve: resolveToolRenderer as ToolRenderer,
|