veryfront 0.1.337 → 0.1.339

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.
@@ -419,6 +419,30 @@ export {
419
419
  normalizeHostedChildArtifactPath,
420
420
  withHostedChildRerunnableFileWriteFallbacks,
421
421
  } from "./hosted-child-artifact-support.js";
422
+ export {
423
+ buildDefaultResearchArtifactPathReminder,
424
+ buildDefaultResearchArtifactPaths,
425
+ type DefaultResearchArtifactPaths,
426
+ shouldInjectDefaultResearchArtifactPath,
427
+ withDefaultResearchArtifactPath,
428
+ } from "./default-research-artifact-policy.js";
429
+ export {
430
+ applyDefaultResearchArtifactPath,
431
+ type DefaultResearchArtifactContext,
432
+ type DefaultResearchArtifactLogger,
433
+ type DefaultResearchArtifacts,
434
+ extractLatestUserText,
435
+ fetchLatestConversationUserText,
436
+ mirrorDefaultResearchRunArtifact,
437
+ shouldRetryCreateResearchArtifactAsUpdate,
438
+ updateDefaultResearchArtifacts,
439
+ } from "./default-research-artifact-support.js";
440
+ export {
441
+ containsExactArtifactPathValue,
442
+ evaluateSlashCommandArtifactPolicy,
443
+ type SlashCommandArtifactPolicy,
444
+ type SlashCommandArtifactPolicyInput,
445
+ } from "./slash-command-artifact-policy.js";
422
446
  export {
423
447
  buildHostedChildCompletedLog,
424
448
  buildHostedChildErrorLog,
@@ -0,0 +1,212 @@
1
+ import { isRecord } from "../chat/conversation.js";
2
+
3
+ const SLASH_COMMAND_PATTERN = /(?:^|<span\s+data-command="[^"]+">)\s*\/[a-z0-9_-]+/i;
4
+ const EXACT_ARTIFACT_PATH_PATTERN = /(?:^|[\s`"'(])\/?[\w./-]+\.(?:md|mdx|txt|json|ya?ml)\b/i;
5
+
6
+ export interface SlashCommandArtifactPolicyInput {
7
+ messages: readonly unknown[];
8
+ slashCommandArtifactPathSeen?: boolean;
9
+ }
10
+
11
+ export interface SlashCommandArtifactPolicy {
12
+ hasSlashCommand: boolean;
13
+ hasExactArtifactPath: boolean;
14
+ hasLoadSkill: boolean;
15
+ hasInvokeAgent: boolean;
16
+ shouldKeepReminder: boolean;
17
+ }
18
+
19
+ function isToolCallPart(
20
+ part: unknown,
21
+ ): part is { type: "tool-call"; toolCallId: string; toolName: string } {
22
+ return (
23
+ isRecord(part) &&
24
+ part.type === "tool-call" &&
25
+ typeof part.toolCallId === "string" &&
26
+ typeof part.toolName === "string"
27
+ );
28
+ }
29
+
30
+ function isToolResultPart(part: unknown): part is {
31
+ type: "tool-result";
32
+ toolCallId: string;
33
+ toolName?: string;
34
+ output?: unknown;
35
+ result?: unknown;
36
+ } {
37
+ return isRecord(part) && part.type === "tool-result" && typeof part.toolCallId === "string";
38
+ }
39
+
40
+ function isToolRoleMessage(message: unknown): message is {
41
+ role: "tool";
42
+ toolCallId?: string;
43
+ toolName?: string;
44
+ content: unknown;
45
+ } {
46
+ return isRecord(message) && message.role === "tool" && "content" in message;
47
+ }
48
+
49
+ function parseJsonString(value: string): unknown {
50
+ try {
51
+ return JSON.parse(value);
52
+ } catch {
53
+ return value;
54
+ }
55
+ }
56
+
57
+ function extractArtifactPathsFromUnknown(value: unknown): string[] {
58
+ if (typeof value === "string") {
59
+ return EXACT_ARTIFACT_PATH_PATTERN.test(value) ? [value] : [];
60
+ }
61
+
62
+ if (Array.isArray(value)) {
63
+ return value.flatMap((item) => extractArtifactPathsFromUnknown(item));
64
+ }
65
+
66
+ if (!isRecord(value)) {
67
+ return [];
68
+ }
69
+
70
+ return Object.values(value).flatMap((nestedValue) =>
71
+ extractArtifactPathsFromUnknown(nestedValue)
72
+ );
73
+ }
74
+
75
+ function extractMessageTexts(content: unknown): string[] {
76
+ if (typeof content === "string" && content.trim().length > 0) {
77
+ return [content];
78
+ }
79
+
80
+ if (!Array.isArray(content)) {
81
+ return [];
82
+ }
83
+
84
+ return content.flatMap((part) =>
85
+ isRecord(part) && part.type === "text" && typeof part.text === "string" &&
86
+ part.text.trim().length > 0
87
+ ? [part.text]
88
+ : []
89
+ );
90
+ }
91
+
92
+ function resolveToolName(
93
+ toolCallNamesById: ReadonlyMap<string, string>,
94
+ value: { toolName?: string; toolCallId?: string },
95
+ ): string | undefined {
96
+ if (typeof value.toolName === "string" && value.toolName.length > 0) {
97
+ return value.toolName;
98
+ }
99
+
100
+ return typeof value.toolCallId === "string" ? toolCallNamesById.get(value.toolCallId) : undefined;
101
+ }
102
+
103
+ function hasToolCallOrResult(messages: readonly unknown[], toolName: string): boolean {
104
+ return messages.some((message) => {
105
+ if (!isRecord(message) || !Array.isArray(message.content)) {
106
+ return false;
107
+ }
108
+
109
+ return message.content.some((part) => {
110
+ if (!isRecord(part) || typeof part.toolName !== "string") {
111
+ return false;
112
+ }
113
+
114
+ return (part.type === "tool-call" || part.type === "tool-result") &&
115
+ part.toolName === toolName;
116
+ });
117
+ });
118
+ }
119
+
120
+ function containsSlashCommand(messages: readonly unknown[]): boolean {
121
+ return messages.some((message) => {
122
+ if (!isRecord(message) || message.role !== "user") {
123
+ return false;
124
+ }
125
+
126
+ return extractMessageTexts(message.content).some((text) => SLASH_COMMAND_PATTERN.test(text));
127
+ });
128
+ }
129
+
130
+ function containsExactArtifactPath(messages: readonly unknown[]): boolean {
131
+ const toolCallNamesById = new Map<string, string>();
132
+
133
+ for (const message of messages) {
134
+ if (!isRecord(message) || !Array.isArray(message.content)) {
135
+ continue;
136
+ }
137
+
138
+ for (const part of message.content) {
139
+ if (!isToolCallPart(part)) {
140
+ continue;
141
+ }
142
+
143
+ toolCallNamesById.set(part.toolCallId, part.toolName);
144
+ }
145
+ }
146
+
147
+ return messages.some((message) => {
148
+ if (!isRecord(message)) {
149
+ return false;
150
+ }
151
+
152
+ if (message.role === "user") {
153
+ return extractMessageTexts(message.content).some((text) =>
154
+ EXACT_ARTIFACT_PATH_PATTERN.test(text)
155
+ );
156
+ }
157
+
158
+ if (isToolRoleMessage(message) && !Array.isArray(message.content)) {
159
+ const resolvedToolName = resolveToolName(toolCallNamesById, message);
160
+
161
+ if (resolvedToolName !== "form_input") {
162
+ return false;
163
+ }
164
+
165
+ const parsedContent = typeof message.content === "string"
166
+ ? parseJsonString(message.content)
167
+ : message.content;
168
+ return containsExactArtifactPathValue(parsedContent);
169
+ }
170
+
171
+ if (!Array.isArray(message.content)) {
172
+ return false;
173
+ }
174
+
175
+ return message.content.some((part) => {
176
+ if (!isToolResultPart(part) || !isRecord(part)) {
177
+ return false;
178
+ }
179
+
180
+ const resolvedToolName = resolveToolName(toolCallNamesById, part);
181
+
182
+ if (resolvedToolName !== "form_input") {
183
+ return false;
184
+ }
185
+
186
+ return containsExactArtifactPathValue(part.output) ||
187
+ containsExactArtifactPathValue(part.result);
188
+ });
189
+ });
190
+ }
191
+
192
+ export function containsExactArtifactPathValue(value: unknown): boolean {
193
+ return extractArtifactPathsFromUnknown(value).length > 0;
194
+ }
195
+
196
+ export function evaluateSlashCommandArtifactPolicy(
197
+ input: SlashCommandArtifactPolicyInput,
198
+ ): SlashCommandArtifactPolicy {
199
+ const hasSlashCommand = containsSlashCommand(input.messages);
200
+ const hasExactArtifactPath = containsExactArtifactPath(input.messages) ||
201
+ input.slashCommandArtifactPathSeen === true;
202
+ const hasLoadSkill = hasToolCallOrResult(input.messages, "load_skill");
203
+ const hasInvokeAgent = hasToolCallOrResult(input.messages, "invoke_agent");
204
+
205
+ return {
206
+ hasSlashCommand,
207
+ hasExactArtifactPath,
208
+ hasLoadSkill,
209
+ hasInvokeAgent,
210
+ shouldKeepReminder: hasSlashCommand && hasExactArtifactPath && hasLoadSkill && !hasInvokeAgent,
211
+ };
212
+ }
@@ -1,3 +1,3 @@
1
1
  // Keep in sync with deno.json version.
2
2
  // scripts/release.ts updates this constant during releases.
3
- export const VERSION = "0.1.337";
3
+ export const VERSION = "0.1.339";