@namzu/sdk 45.0.0 → 46.0.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/CHANGELOG.md +166 -0
- package/dist/authorization/gate.d.ts +5 -2
- package/dist/authorization/gate.d.ts.map +1 -1
- package/dist/authorization/gate.js +35 -4
- package/dist/authorization/gate.js.map +1 -1
- package/dist/authorization/rules.d.ts.map +1 -1
- package/dist/authorization/rules.js +56 -6
- package/dist/authorization/rules.js.map +1 -1
- package/dist/authorization/shell-lexer.d.ts +38 -0
- package/dist/authorization/shell-lexer.d.ts.map +1 -1
- package/dist/authorization/shell-lexer.js +88 -57
- package/dist/authorization/shell-lexer.js.map +1 -1
- package/dist/bridge/a2a/mapper.d.ts.map +1 -1
- package/dist/bridge/a2a/mapper.js +2 -0
- package/dist/bridge/a2a/mapper.js.map +1 -1
- package/dist/bridge/sse/mapper.d.ts.map +1 -1
- package/dist/bridge/sse/mapper.js +1 -0
- package/dist/bridge/sse/mapper.js.map +1 -1
- package/dist/directory/types.d.ts +2 -0
- package/dist/directory/types.d.ts.map +1 -1
- package/dist/directory/types.js.map +1 -1
- package/dist/manager/resident/outbox.d.ts +4 -4
- package/dist/pricing/catalogue.generated.d.ts.map +1 -1
- package/dist/pricing/catalogue.generated.js +28 -4
- package/dist/pricing/catalogue.generated.js.map +1 -1
- package/dist/prompt/coding-agent-doctrine.d.ts +1 -1
- package/dist/prompt/coding-agent-doctrine.d.ts.map +1 -1
- package/dist/prompt/coding-agent-doctrine.js +1 -0
- package/dist/prompt/coding-agent-doctrine.js.map +1 -1
- package/dist/public-runtime.d.ts +6 -3
- package/dist/public-runtime.d.ts.map +1 -1
- package/dist/public-runtime.js +14 -2
- package/dist/public-runtime.js.map +1 -1
- package/dist/public-tools.d.ts +7 -2
- package/dist/public-tools.d.ts.map +1 -1
- package/dist/public-tools.js +15 -2
- package/dist/public-tools.js.map +1 -1
- package/dist/public-types.d.ts +8 -2
- package/dist/public-types.d.ts.map +1 -1
- package/dist/registry/tool/callable.d.ts +22 -0
- package/dist/registry/tool/callable.d.ts.map +1 -0
- package/dist/registry/tool/callable.js +29 -0
- package/dist/registry/tool/callable.js.map +1 -0
- package/dist/registry/tool/execute.d.ts.map +1 -1
- package/dist/registry/tool/execute.js +8 -1
- package/dist/registry/tool/execute.js.map +1 -1
- package/dist/runtime/query/declined.d.ts +12 -0
- package/dist/runtime/query/declined.d.ts.map +1 -0
- package/dist/runtime/query/declined.js +12 -0
- package/dist/runtime/query/declined.js.map +1 -0
- package/dist/runtime/query/executor/tool-call-admission.d.ts +37 -11
- package/dist/runtime/query/executor/tool-call-admission.d.ts.map +1 -1
- package/dist/runtime/query/executor/tool-call-admission.js +38 -12
- package/dist/runtime/query/executor/tool-call-admission.js.map +1 -1
- package/dist/runtime/query/executor.d.ts +7 -3
- package/dist/runtime/query/executor.d.ts.map +1 -1
- package/dist/runtime/query/executor.js +32 -7
- package/dist/runtime/query/executor.js.map +1 -1
- package/dist/runtime/query/index.d.ts.map +1 -1
- package/dist/runtime/query/index.js +1 -0
- package/dist/runtime/query/index.js.map +1 -1
- package/dist/runtime/query/iteration/index.d.ts.map +1 -1
- package/dist/runtime/query/iteration/index.js +7 -0
- package/dist/runtime/query/iteration/index.js.map +1 -1
- package/dist/runtime/query/iteration/phases/context.d.ts +6 -0
- package/dist/runtime/query/iteration/phases/context.d.ts.map +1 -1
- package/dist/runtime/query/iteration/phases/context.js.map +1 -1
- package/dist/runtime/query/iteration/phases/handoff.d.ts +22 -0
- package/dist/runtime/query/iteration/phases/handoff.d.ts.map +1 -0
- package/dist/runtime/query/iteration/phases/handoff.js +65 -0
- package/dist/runtime/query/iteration/phases/handoff.js.map +1 -0
- package/dist/runtime/query/iteration/phases/index.d.ts +1 -0
- package/dist/runtime/query/iteration/phases/index.d.ts.map +1 -1
- package/dist/runtime/query/iteration/phases/index.js +1 -0
- package/dist/runtime/query/iteration/phases/index.js.map +1 -1
- package/dist/runtime/query/iteration/phases/tool-review.d.ts.map +1 -1
- package/dist/runtime/query/iteration/phases/tool-review.js +8 -3
- package/dist/runtime/query/iteration/phases/tool-review.js.map +1 -1
- package/dist/runtime/query/resume-pending.d.ts.map +1 -1
- package/dist/runtime/query/resume-pending.js +3 -2
- package/dist/runtime/query/resume-pending.js.map +1 -1
- package/dist/runtime/query/review-policy.d.ts +43 -0
- package/dist/runtime/query/review-policy.d.ts.map +1 -1
- package/dist/runtime/query/review-policy.js +63 -19
- package/dist/runtime/query/review-policy.js.map +1 -1
- package/dist/schedules/cron.d.ts +21 -0
- package/dist/schedules/cron.d.ts.map +1 -0
- package/dist/schedules/cron.js +167 -0
- package/dist/schedules/cron.js.map +1 -0
- package/dist/schedules/describe.d.ts +14 -0
- package/dist/schedules/describe.d.ts.map +1 -0
- package/dist/schedules/describe.js +133 -0
- package/dist/schedules/describe.js.map +1 -0
- package/dist/schedules/errors.d.ts +11 -0
- package/dist/schedules/errors.d.ts.map +1 -0
- package/dist/schedules/errors.js +15 -0
- package/dist/schedules/errors.js.map +1 -0
- package/dist/schedules/evaluate.d.ts +35 -0
- package/dist/schedules/evaluate.d.ts.map +1 -0
- package/dist/schedules/evaluate.js +158 -0
- package/dist/schedules/evaluate.js.map +1 -0
- package/dist/schedules/index.d.ts +11 -0
- package/dist/schedules/index.d.ts.map +1 -0
- package/dist/schedules/index.js +8 -0
- package/dist/schedules/index.js.map +1 -0
- package/dist/schedules/next-fire.d.ts +50 -0
- package/dist/schedules/next-fire.d.ts.map +1 -0
- package/dist/schedules/next-fire.js +250 -0
- package/dist/schedules/next-fire.js.map +1 -0
- package/dist/schedules/spec.d.ts +30 -0
- package/dist/schedules/spec.d.ts.map +1 -0
- package/dist/schedules/spec.js +169 -0
- package/dist/schedules/spec.js.map +1 -0
- package/dist/schedules/types.d.ts +144 -0
- package/dist/schedules/types.d.ts.map +1 -0
- package/dist/schedules/types.js +11 -0
- package/dist/schedules/types.js.map +1 -0
- package/dist/schedules/tz.d.ts +44 -0
- package/dist/schedules/tz.d.ts.map +1 -0
- package/dist/schedules/tz.js +141 -0
- package/dist/schedules/tz.js.map +1 -0
- package/dist/skills/index.d.ts +1 -1
- package/dist/skills/index.d.ts.map +1 -1
- package/dist/skills/index.js +1 -1
- package/dist/skills/index.js.map +1 -1
- package/dist/skills/loader.d.ts +16 -3
- package/dist/skills/loader.d.ts.map +1 -1
- package/dist/skills/loader.js +48 -4
- package/dist/skills/loader.js.map +1 -1
- package/dist/skills/registry.d.ts +6 -0
- package/dist/skills/registry.d.ts.map +1 -1
- package/dist/skills/registry.js +1 -0
- package/dist/skills/registry.js.map +1 -1
- package/dist/tools/builtins/browser-url.d.ts +83 -0
- package/dist/tools/builtins/browser-url.d.ts.map +1 -0
- package/dist/tools/builtins/browser-url.js +240 -0
- package/dist/tools/builtins/browser-url.js.map +1 -0
- package/dist/tools/builtins/browser.d.ts +367 -0
- package/dist/tools/builtins/browser.d.ts.map +1 -0
- package/dist/tools/builtins/browser.js +704 -0
- package/dist/tools/builtins/browser.js.map +1 -0
- package/dist/tools/builtins/computer-use-coordinates.d.ts +65 -0
- package/dist/tools/builtins/computer-use-coordinates.d.ts.map +1 -0
- package/dist/tools/builtins/computer-use-coordinates.js +123 -0
- package/dist/tools/builtins/computer-use-coordinates.js.map +1 -0
- package/dist/tools/builtins/computer-use-image.d.ts +77 -0
- package/dist/tools/builtins/computer-use-image.d.ts.map +1 -0
- package/dist/tools/builtins/computer-use-image.js +223 -0
- package/dist/tools/builtins/computer-use-image.js.map +1 -0
- package/dist/tools/builtins/computer-use.d.ts +519 -14
- package/dist/tools/builtins/computer-use.d.ts.map +1 -1
- package/dist/tools/builtins/computer-use.js +1188 -183
- package/dist/tools/builtins/computer-use.js.map +1 -1
- package/dist/tools/builtins/index.d.ts +2 -1
- package/dist/tools/builtins/index.d.ts.map +1 -1
- package/dist/tools/builtins/index.js +1 -1
- package/dist/tools/builtins/index.js.map +1 -1
- package/dist/tools/builtins/skill.d.ts +74 -0
- package/dist/tools/builtins/skill.d.ts.map +1 -1
- package/dist/tools/builtins/skill.js +214 -159
- package/dist/tools/builtins/skill.js.map +1 -1
- package/dist/tools/defineTool.d.ts +4 -0
- package/dist/tools/defineTool.d.ts.map +1 -1
- package/dist/tools/defineTool.js +8 -0
- package/dist/tools/defineTool.js.map +1 -1
- package/dist/tools/schedules/index.d.ts +5 -0
- package/dist/tools/schedules/index.d.ts.map +1 -0
- package/dist/tools/schedules/index.js +4 -0
- package/dist/tools/schedules/index.js.map +1 -0
- package/dist/tools/schedules/loop-tool.d.ts +14 -0
- package/dist/tools/schedules/loop-tool.d.ts.map +1 -0
- package/dist/tools/schedules/loop-tool.js +81 -0
- package/dist/tools/schedules/loop-tool.js.map +1 -0
- package/dist/tools/schedules/present.d.ts +16 -0
- package/dist/tools/schedules/present.d.ts.map +1 -0
- package/dist/tools/schedules/present.js +71 -0
- package/dist/tools/schedules/present.js.map +1 -0
- package/dist/tools/schedules/prompt-scan.d.ts +17 -0
- package/dist/tools/schedules/prompt-scan.d.ts.map +1 -0
- package/dist/tools/schedules/prompt-scan.js +92 -0
- package/dist/tools/schedules/prompt-scan.js.map +1 -0
- package/dist/tools/schedules/schedule-tool.d.ts +17 -0
- package/dist/tools/schedules/schedule-tool.d.ts.map +1 -0
- package/dist/tools/schedules/schedule-tool.js +418 -0
- package/dist/tools/schedules/schedule-tool.js.map +1 -0
- package/dist/tools/schedules/types.d.ts +252 -0
- package/dist/tools/schedules/types.d.ts.map +1 -0
- package/dist/tools/schedules/types.js +11 -0
- package/dist/tools/schedules/types.js.map +1 -0
- package/dist/types/authorization/index.d.ts +107 -9
- package/dist/types/authorization/index.d.ts.map +1 -1
- package/dist/types/authorization/index.js +16 -1
- package/dist/types/authorization/index.js.map +1 -1
- package/dist/types/browser/index.d.ts +280 -0
- package/dist/types/browser/index.d.ts.map +1 -0
- package/dist/types/browser/index.js +12 -0
- package/dist/types/browser/index.js.map +1 -0
- package/dist/types/computer-use/index.d.ts +176 -0
- package/dist/types/computer-use/index.d.ts.map +1 -1
- package/dist/types/computer-use/index.js.map +1 -1
- package/dist/types/session/events.d.ts +6 -0
- package/dist/types/session/events.d.ts.map +1 -1
- package/dist/types/session/events.js.map +1 -1
- package/dist/types/session/records.d.ts +23 -0
- package/dist/types/session/records.d.ts.map +1 -1
- package/dist/types/session/records.js +9 -0
- package/dist/types/session/records.js.map +1 -1
- package/dist/types/tool/index.d.ts +60 -0
- package/dist/types/tool/index.d.ts.map +1 -1
- package/dist/types/tool/index.js.map +1 -1
- package/dist/types/tool/presentation.d.ts +7 -0
- package/dist/types/tool/presentation.d.ts.map +1 -1
- package/dist/utils/frontmatter.d.ts +18 -2
- package/dist/utils/frontmatter.d.ts.map +1 -1
- package/dist/utils/frontmatter.js +13 -3
- package/dist/utils/frontmatter.js.map +1 -1
- package/dist/utils/id.d.ts +8 -0
- package/dist/utils/id.d.ts.map +1 -1
- package/dist/utils/id.js +12 -0
- package/dist/utils/id.js.map +1 -1
- package/package.json +3 -1
- package/src/authorization/gate.ts +37 -4
- package/src/authorization/rules.ts +55 -7
- package/src/authorization/shell-lexer.ts +109 -51
- package/src/bridge/a2a/mapper.ts +2 -0
- package/src/bridge/sse/mapper.ts +1 -0
- package/src/directory/types.ts +2 -0
- package/src/pricing/catalogue.generated.ts +28 -4
- package/src/pricing/rates.source.json +27 -6
- package/src/prompt/coding-agent-doctrine.ts +1 -0
- package/src/public-runtime.ts +43 -1
- package/src/public-tools.ts +54 -1
- package/src/public-types.ts +55 -0
- package/src/registry/tool/callable.ts +37 -0
- package/src/registry/tool/execute.ts +8 -1
- package/src/runtime/query/declined.ts +12 -0
- package/src/runtime/query/executor/tool-call-admission.ts +60 -16
- package/src/runtime/query/executor.ts +36 -5
- package/src/runtime/query/index.ts +1 -0
- package/src/runtime/query/iteration/index.ts +8 -0
- package/src/runtime/query/iteration/phases/context.ts +6 -0
- package/src/runtime/query/iteration/phases/handoff.ts +74 -0
- package/src/runtime/query/iteration/phases/index.ts +1 -0
- package/src/runtime/query/iteration/phases/tool-review.ts +11 -4
- package/src/runtime/query/resume-pending.ts +3 -2
- package/src/runtime/query/review-policy.ts +107 -18
- package/src/schedules/cron.ts +202 -0
- package/src/schedules/describe.ts +138 -0
- package/src/schedules/errors.ts +15 -0
- package/src/schedules/evaluate.ts +178 -0
- package/src/schedules/index.ts +18 -0
- package/src/schedules/next-fire.ts +257 -0
- package/src/schedules/spec.ts +210 -0
- package/src/schedules/types.ts +163 -0
- package/src/schedules/tz.ts +155 -0
- package/src/skills/index.ts +1 -1
- package/src/skills/loader.ts +55 -4
- package/src/skills/registry.ts +8 -0
- package/src/tools/builtins/browser-url.ts +251 -0
- package/src/tools/builtins/browser.ts +817 -0
- package/src/tools/builtins/computer-use-coordinates.ts +144 -0
- package/src/tools/builtins/computer-use-image.ts +278 -0
- package/src/tools/builtins/computer-use.ts +1485 -191
- package/src/tools/builtins/index.ts +7 -1
- package/src/tools/builtins/skill.ts +304 -156
- package/src/tools/defineTool.ts +13 -0
- package/src/tools/schedules/index.ts +4 -0
- package/src/tools/schedules/loop-tool.ts +85 -0
- package/src/tools/schedules/present.ts +88 -0
- package/src/tools/schedules/prompt-scan.ts +96 -0
- package/src/tools/schedules/schedule-tool.ts +482 -0
- package/src/tools/schedules/types.ts +265 -0
- package/src/types/authorization/index.ts +81 -2
- package/src/types/browser/index.ts +341 -0
- package/src/types/computer-use/index.ts +202 -0
- package/src/types/session/events.ts +6 -0
- package/src/types/session/records.ts +10 -0
- package/src/types/tool/index.ts +61 -0
- package/src/types/tool/presentation.ts +7 -0
- package/src/utils/frontmatter.ts +29 -3
- package/src/utils/id.ts +14 -0
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import { z } from 'zod'
|
|
2
|
+
import type { ToolDefinition } from '../../types/tool/index.js'
|
|
3
|
+
import { defineTool } from '../defineTool.js'
|
|
4
|
+
import { presentLoopCall, presentLoopResult } from './present.js'
|
|
5
|
+
import type { SessionLoopHost } from './types.js'
|
|
6
|
+
|
|
7
|
+
export const SESSION_LOOP_TOOL_NAME = 'session_loop'
|
|
8
|
+
|
|
9
|
+
const inputSchema = z.object({
|
|
10
|
+
action: z.enum(['create', 'list', 'delete']),
|
|
11
|
+
interval: z
|
|
12
|
+
.string()
|
|
13
|
+
.optional()
|
|
14
|
+
.describe('create: how often, e.g. "5m", "1h", or a five-field cron expression'),
|
|
15
|
+
prompt: z.string().min(1).max(4_000).optional().describe('create: the message to send each time'),
|
|
16
|
+
id: z.string().optional().describe('delete: the loop id, or "all"'),
|
|
17
|
+
})
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* The `session_loop` tool: re-send a prompt to THIS conversation on an
|
|
21
|
+
* interval, between turns, while the session is open.
|
|
22
|
+
*
|
|
23
|
+
* `create` is an ordinary reviewed call — not exempt from review — so in
|
|
24
|
+
* `prompt` mode the operator sees it before a loop exists; a loop a model
|
|
25
|
+
* created is labelled as such wherever it is shown. `list` and `delete` only
|
|
26
|
+
* read or remove loops.
|
|
27
|
+
*/
|
|
28
|
+
export function buildSessionLoopTools(host: SessionLoopHost): ToolDefinition[] {
|
|
29
|
+
return [
|
|
30
|
+
defineTool({
|
|
31
|
+
name: SESSION_LOOP_TOOL_NAME,
|
|
32
|
+
description:
|
|
33
|
+
'Re-send a prompt to this conversation on an interval while the session stays open (between turns only; stops when the session closes; expires after 7 days). Use only when the user asks for something to repeat. Minimum interval one minute.',
|
|
34
|
+
inputSchema,
|
|
35
|
+
category: 'custom',
|
|
36
|
+
permissions: [],
|
|
37
|
+
readOnly: (input) => input.action !== 'create',
|
|
38
|
+
destructive: false,
|
|
39
|
+
concurrencySafe: false,
|
|
40
|
+
presentCall: presentLoopCall,
|
|
41
|
+
presentResult: presentLoopResult,
|
|
42
|
+
async execute(input) {
|
|
43
|
+
if (input.action === 'list') {
|
|
44
|
+
const loops = host.list()
|
|
45
|
+
return {
|
|
46
|
+
success: true,
|
|
47
|
+
output:
|
|
48
|
+
loops.length === 0
|
|
49
|
+
? 'No loops in this session.'
|
|
50
|
+
: loops.map((l) => `${l.id} · ${l.schedule} · ${l.prompt.slice(0, 80)}`).join('\n'),
|
|
51
|
+
data: { loops },
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
if (input.action === 'delete') {
|
|
55
|
+
if (!input.id) return { success: false, output: '', error: 'delete needs id (or "all").' }
|
|
56
|
+
const stopped = await host.delete(input.id)
|
|
57
|
+
return stopped === 0
|
|
58
|
+
? { success: false, output: '', error: `No loop has id "${input.id}".` }
|
|
59
|
+
: { success: true, output: `Stopped ${stopped} loop${stopped === 1 ? '' : 's'}.` }
|
|
60
|
+
}
|
|
61
|
+
if (!input.interval || !input.prompt) {
|
|
62
|
+
return { success: false, output: '', error: 'create needs interval and prompt.' }
|
|
63
|
+
}
|
|
64
|
+
try {
|
|
65
|
+
const loop = await host.create({
|
|
66
|
+
interval: input.interval,
|
|
67
|
+
prompt: input.prompt,
|
|
68
|
+
createdBy: 'model',
|
|
69
|
+
})
|
|
70
|
+
return {
|
|
71
|
+
success: true,
|
|
72
|
+
output: `Loop ${loop.id} created: ${loop.schedule}. The operator can stop it with /loop stop ${loop.id}.`,
|
|
73
|
+
data: { id: loop.id },
|
|
74
|
+
}
|
|
75
|
+
} catch (error) {
|
|
76
|
+
return {
|
|
77
|
+
success: false,
|
|
78
|
+
output: '',
|
|
79
|
+
error: error instanceof Error ? error.message : String(error),
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
},
|
|
83
|
+
}),
|
|
84
|
+
]
|
|
85
|
+
}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import type { ToolResult } from '../../types/tool/index.js'
|
|
2
|
+
import type { ToolCallView, ToolResultView } from '../../types/tool/presentation.js'
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* How the schedule tools read to a person: in words, never ids or JSON.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
const MAX = 80
|
|
9
|
+
|
|
10
|
+
function oneLine(value: unknown): string {
|
|
11
|
+
if (typeof value !== 'string') return ''
|
|
12
|
+
const flat = value.replace(/\s+/g, ' ').trim()
|
|
13
|
+
return flat.length > MAX ? `${flat.slice(0, MAX - 1)}…` : flat
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
function activity(label: string): ToolCallView {
|
|
17
|
+
return { kind: 'generic', presentation: 'activity', label }
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
const HIDDEN: ToolResultView = { kind: 'generic', label: '', visibility: 'hidden' }
|
|
21
|
+
|
|
22
|
+
export function presentScheduleCall(input: {
|
|
23
|
+
readonly action?: unknown
|
|
24
|
+
readonly name?: unknown
|
|
25
|
+
readonly when?: unknown
|
|
26
|
+
readonly job?: unknown
|
|
27
|
+
}): ToolCallView {
|
|
28
|
+
switch (input.action) {
|
|
29
|
+
case 'create': {
|
|
30
|
+
const name = oneLine(input.name)
|
|
31
|
+
const when = oneLine(input.when)
|
|
32
|
+
return activity(`Propose scheduled job${name ? ` · ${name}` : ''}${when ? ` · ${when}` : ''}`)
|
|
33
|
+
}
|
|
34
|
+
case 'list':
|
|
35
|
+
return activity('List scheduled jobs')
|
|
36
|
+
case 'update':
|
|
37
|
+
return activity(`Change scheduled job · ${oneLine(input.job)}`)
|
|
38
|
+
case 'pause':
|
|
39
|
+
return activity(`Pause scheduled job · ${oneLine(input.job)}`)
|
|
40
|
+
case 'resume':
|
|
41
|
+
return activity(`Resume scheduled job · ${oneLine(input.job)}`)
|
|
42
|
+
case 'delete':
|
|
43
|
+
return activity(`Delete scheduled job · ${oneLine(input.job)}`)
|
|
44
|
+
default:
|
|
45
|
+
return activity('Scheduled jobs')
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/** The operator answered no on the tool's own screen: not a failure. */
|
|
50
|
+
function operatorCancelled(result: ToolResult): boolean {
|
|
51
|
+
const data = result.data as { cancelled?: unknown } | undefined
|
|
52
|
+
return data?.cancelled === true
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
export function presentScheduleResult(input: unknown, result: ToolResult): ToolResultView {
|
|
56
|
+
if (!result.success && operatorCancelled(result)) {
|
|
57
|
+
const action = (input as { action?: unknown } | null)?.action
|
|
58
|
+
return {
|
|
59
|
+
kind: 'generic',
|
|
60
|
+
outcome: 'cancelled',
|
|
61
|
+
label: action === 'create' ? 'Cancelled — no job was created' : 'Cancelled — nothing changed',
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
if (!result.success) return { kind: 'generic', label: oneLine(result.error) || 'Not done' }
|
|
65
|
+
return HIDDEN
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
export function presentLoopCall(input: {
|
|
69
|
+
readonly action?: unknown
|
|
70
|
+
readonly interval?: unknown
|
|
71
|
+
readonly prompt?: unknown
|
|
72
|
+
}): ToolCallView {
|
|
73
|
+
switch (input.action) {
|
|
74
|
+
case 'create':
|
|
75
|
+
return activity(`Loop ${oneLine(input.interval)} · ${oneLine(input.prompt)}`)
|
|
76
|
+
case 'list':
|
|
77
|
+
return activity('List loops')
|
|
78
|
+
case 'delete':
|
|
79
|
+
return activity('Stop loop')
|
|
80
|
+
default:
|
|
81
|
+
return activity('Loops')
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
export function presentLoopResult(_input: unknown, result: ToolResult): ToolResultView {
|
|
86
|
+
if (!result.success) return { kind: 'generic', label: oneLine(result.error) || 'Not done' }
|
|
87
|
+
return HIDDEN
|
|
88
|
+
}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A tripwire over a scheduled prompt, run when the job is proposed.
|
|
3
|
+
*
|
|
4
|
+
* A scheduled prompt runs later with nobody watching, so a prompt that hides
|
|
5
|
+
* characters, tells the model to ignore its instructions, or reads secrets and
|
|
6
|
+
* sends them somewhere deserves a second look before anyone confirms it.
|
|
7
|
+
* Findings are shown to the person confirming; they never block on their own,
|
|
8
|
+
* because the operator may mean exactly what they wrote.
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
/** Characters that render as nothing or reorder what is shown. */
|
|
12
|
+
/** Invisible and direction-changing code point ranges, inclusive. */
|
|
13
|
+
const INVISIBLE_RANGES: readonly (readonly [number, number])[] = [
|
|
14
|
+
[0x200b, 0x200f],
|
|
15
|
+
[0x202a, 0x202e],
|
|
16
|
+
[0x2060, 0x2064],
|
|
17
|
+
[0x2066, 0x2069],
|
|
18
|
+
[0xfeff, 0xfeff],
|
|
19
|
+
[0x00ad, 0x00ad],
|
|
20
|
+
]
|
|
21
|
+
|
|
22
|
+
function isInvisible(code: number): boolean {
|
|
23
|
+
return INVISIBLE_RANGES.some(([lo, hi]) => code >= lo && code <= hi)
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function hasInvisible(text: string): boolean {
|
|
27
|
+
for (const ch of text) if (isInvisible(ch.codePointAt(0) ?? 0)) return true
|
|
28
|
+
return false
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/** C0 controls other than tab, newline and carriage return, and DEL. */
|
|
32
|
+
function isControl(code: number): boolean {
|
|
33
|
+
return (code < 0x20 && code !== 0x09 && code !== 0x0a && code !== 0x0d) || code === 0x7f
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
function hasControl(text: string): boolean {
|
|
37
|
+
for (let i = 0; i < text.length; i++) if (isControl(text.charCodeAt(i))) return true
|
|
38
|
+
return false
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
const DIRECTIVES: readonly RegExp[] = [
|
|
42
|
+
/\bignore (all |any )?(the )?(previous|prior|above|earlier) (instructions|rules|messages)\b/i,
|
|
43
|
+
/\bdisregard (all |any )?(the )?(previous|prior|above|system) /i,
|
|
44
|
+
/\b(reveal|print|show|repeat) (your|the) (system prompt|instructions)\b/i,
|
|
45
|
+
/\byou are no longer\b/i,
|
|
46
|
+
]
|
|
47
|
+
|
|
48
|
+
const SECRET_READS: readonly RegExp[] = [
|
|
49
|
+
/~?\/?\.ssh\b|\bid_(rsa|ed25519|ecdsa)\b/i,
|
|
50
|
+
/\.aws\/credentials|\.config\/gcloud|\.kube\/config|\.netrc\b|\.npmrc\b|\.pypirc\b/i,
|
|
51
|
+
/\bcredentials\.json\b|\.env\b/i,
|
|
52
|
+
/\b(printenv|env)\b\s*($|[|;&>])/i,
|
|
53
|
+
/\b[A-Z0-9_]*(API_KEY|SECRET|TOKEN|PASSWORD)\b/,
|
|
54
|
+
]
|
|
55
|
+
|
|
56
|
+
const EXFILTRATION: readonly RegExp[] = [
|
|
57
|
+
/\b(curl|wget)\b[^\n|]*\|\s*(ba|z|da)?sh\b/i,
|
|
58
|
+
/\bcurl\b[^\n]*\s(-d|--data(-binary|-raw)?|-F|--form|-T|--upload-file|-X\s*(POST|PUT))\b/i,
|
|
59
|
+
/\b(nc|ncat|netcat|socat)\b\s+\S+\s+\d+/i,
|
|
60
|
+
/\bbase64\b[^\n]*\|\s*(curl|wget|nc)\b/i,
|
|
61
|
+
]
|
|
62
|
+
|
|
63
|
+
/** What the scan found, as sentences for the confirmation screen. Empty when nothing. */
|
|
64
|
+
export function scanSchedulePrompt(prompt: string): string[] {
|
|
65
|
+
const findings: string[] = []
|
|
66
|
+
if (hasInvisible(prompt)) {
|
|
67
|
+
findings.push('The prompt contains invisible or direction-changing characters.')
|
|
68
|
+
}
|
|
69
|
+
if (hasControl(prompt)) findings.push('The prompt contains control characters.')
|
|
70
|
+
if (DIRECTIVES.some((re) => re.test(prompt))) {
|
|
71
|
+
findings.push('The prompt tells the model to ignore or reveal its instructions.')
|
|
72
|
+
}
|
|
73
|
+
if (SECRET_READS.some((re) => re.test(prompt))) {
|
|
74
|
+
findings.push('The prompt mentions credentials, keys or secret files.')
|
|
75
|
+
}
|
|
76
|
+
if (EXFILTRATION.some((re) => re.test(prompt))) {
|
|
77
|
+
findings.push('The prompt pipes a download into a shell or sends data to a remote address.')
|
|
78
|
+
}
|
|
79
|
+
return findings
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* The prompt with every invisible and control character made visible as
|
|
84
|
+
* `<U+XXXX>`, so the person confirming sees what the model will read.
|
|
85
|
+
*/
|
|
86
|
+
export function revealHiddenCharacters(prompt: string): string {
|
|
87
|
+
let out = ''
|
|
88
|
+
for (const ch of prompt) {
|
|
89
|
+
const code = ch.codePointAt(0) ?? 0
|
|
90
|
+
out +=
|
|
91
|
+
isControl(code) || isInvisible(code)
|
|
92
|
+
? `<U+${code.toString(16).toUpperCase().padStart(4, '0')}>`
|
|
93
|
+
: ch
|
|
94
|
+
}
|
|
95
|
+
return out
|
|
96
|
+
}
|