neoctl 0.2.35 → 0.2.37
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/agents/agent-report-security.test.d.ts +1 -0
- package/dist/agents/agent-report-security.test.js +301 -0
- package/dist/agents/agent-report-security.test.js.map +1 -0
- package/dist/agents/agent-tool-persistence.test.d.ts +1 -0
- package/dist/agents/agent-tool-persistence.test.js +319 -0
- package/dist/agents/agent-tool-persistence.test.js.map +1 -0
- package/dist/agents/agent-tool.d.ts +3 -0
- package/dist/agents/agent-tool.js +246 -76
- package/dist/agents/agent-tool.js.map +1 -1
- package/dist/agents/live-preview-redaction-security.test.d.ts +1 -0
- package/dist/agents/live-preview-redaction-security.test.js +286 -0
- package/dist/agents/live-preview-redaction-security.test.js.map +1 -0
- package/dist/agents/local-agent-task.d.ts +68 -1
- package/dist/agents/local-agent-task.js +78 -5
- package/dist/agents/local-agent-task.js.map +1 -1
- package/dist/agents/no-nested-delegation.test.d.ts +1 -0
- package/dist/agents/no-nested-delegation.test.js +38 -0
- package/dist/agents/no-nested-delegation.test.js.map +1 -0
- package/dist/agents/obs07-11-run-facts.test.d.ts +1 -0
- package/dist/agents/obs07-11-run-facts.test.js +459 -0
- package/dist/agents/obs07-11-run-facts.test.js.map +1 -0
- package/dist/agents/smoke-agent-lifecycle.d.ts +1 -0
- package/dist/agents/smoke-agent-lifecycle.js +192 -0
- package/dist/agents/smoke-agent-lifecycle.js.map +1 -0
- package/dist/agents/smoke-agents.js +7 -3
- package/dist/agents/smoke-agents.js.map +1 -1
- package/dist/context/context-manager.d.ts +1 -0
- package/dist/context/context-manager.js +10 -6
- package/dist/context/context-manager.js.map +1 -1
- package/dist/context/smoke-context.js +46 -3
- package/dist/context/smoke-context.js.map +1 -1
- package/dist/core/image-registry.js +1 -1
- package/dist/core/image-registry.js.map +1 -1
- package/dist/core/obs04-visible-data.test.d.ts +1 -0
- package/dist/core/obs04-visible-data.test.js +147 -0
- package/dist/core/obs04-visible-data.test.js.map +1 -0
- package/dist/core/query-engine.d.ts +5 -0
- package/dist/core/query-engine.js +36 -3
- package/dist/core/query-engine.js.map +1 -1
- package/dist/core/query.d.ts +5 -1
- package/dist/core/query.js +120 -18
- package/dist/core/query.js.map +1 -1
- package/dist/core/run-agent-pause.test.d.ts +1 -0
- package/dist/core/run-agent-pause.test.js +52 -0
- package/dist/core/run-agent-pause.test.js.map +1 -0
- package/dist/core/run-agent-persistence.test.d.ts +1 -0
- package/dist/core/run-agent-persistence.test.js +222 -0
- package/dist/core/run-agent-persistence.test.js.map +1 -0
- package/dist/core/run-agent.d.ts +13 -0
- package/dist/core/run-agent.js +72 -17
- package/dist/core/run-agent.js.map +1 -1
- package/dist/core/smoke-core-loop.js +8 -7
- package/dist/core/smoke-core-loop.js.map +1 -1
- package/dist/model/model-gateway.d.ts +1 -0
- package/dist/model/openai-native-image-guard.test.d.ts +1 -0
- package/dist/model/openai-native-image-guard.test.js +101 -0
- package/dist/model/openai-native-image-guard.test.js.map +1 -0
- package/dist/model/openai-responses-mapper.js +91 -16
- package/dist/model/openai-responses-mapper.js.map +1 -1
- package/dist/plugins/smoke-plugin-system.js +14 -14
- package/dist/repl/index.js +22 -28
- package/dist/repl/index.js.map +1 -1
- package/dist/secrets/secret-redaction.d.ts +6 -5
- package/dist/secrets/secret-redaction.js +7 -79
- package/dist/secrets/secret-redaction.js.map +1 -1
- package/dist/secrets/secret-types.d.ts +4 -1
- package/dist/secrets/secret-types.js.map +1 -1
- package/dist/session/session-store-safety.test.d.ts +1 -0
- package/dist/session/session-store-safety.test.js +107 -0
- package/dist/session/session-store-safety.test.js.map +1 -0
- package/dist/session/session-store.d.ts +5 -1
- package/dist/session/session-store.js +69 -7
- package/dist/session/session-store.js.map +1 -1
- package/dist/session/tool-result-memory.d.ts +3 -1
- package/dist/session/tool-result-memory.js.map +1 -1
- package/dist/tasks/subagent-tools.d.ts +4 -1
- package/dist/tasks/subagent-tools.js +85 -24
- package/dist/tasks/subagent-tools.js.map +1 -1
- package/dist/tasks/subagent-tools.test.d.ts +1 -0
- package/dist/tasks/subagent-tools.test.js +159 -0
- package/dist/tasks/subagent-tools.test.js.map +1 -0
- package/dist/tasks/task-ack-size.test.d.ts +1 -0
- package/dist/tasks/task-ack-size.test.js +101 -0
- package/dist/tasks/task-ack-size.test.js.map +1 -0
- package/dist/tasks/task-persistence.d.ts +23 -0
- package/dist/tasks/task-persistence.js +216 -0
- package/dist/tasks/task-persistence.js.map +1 -0
- package/dist/tasks/task-persistence.test.d.ts +1 -0
- package/dist/tasks/task-persistence.test.js +331 -0
- package/dist/tasks/task-persistence.test.js.map +1 -0
- package/dist/tasks/task-store.d.ts +51 -7
- package/dist/tasks/task-store.js +333 -31
- package/dist/tasks/task-store.js.map +1 -1
- package/dist/tools/builtins/exec-process-manager.d.ts +97 -2
- package/dist/tools/builtins/exec-process-manager.js +218 -19
- package/dist/tools/builtins/exec-process-manager.js.map +1 -1
- package/dist/tools/builtins/exec-tool.js +14 -1
- package/dist/tools/builtins/exec-tool.js.map +1 -1
- package/dist/tools/builtins/image-generation-tool.js +24 -24
- package/dist/tools/builtins/image-generation-tool.js.map +1 -1
- package/dist/tools/smoke-exec-process.js +2 -1
- package/dist/tools/smoke-exec-process.js.map +1 -1
- package/dist/tools/smoke-terminal-output-chain.d.ts +1 -0
- package/dist/tools/smoke-terminal-output-chain.js +245 -0
- package/dist/tools/smoke-terminal-output-chain.js.map +1 -0
- package/dist/tools/smoke-tool-system.js +6 -6
- package/dist/tools/smoke-tool-system.js.map +1 -1
- package/dist/tools/terminal-output-persistence.test.d.ts +1 -0
- package/dist/tools/terminal-output-persistence.test.js +50 -0
- package/dist/tools/terminal-output-persistence.test.js.map +1 -0
- package/dist/tools/terminal-output-store.d.ts +150 -0
- package/dist/tools/terminal-output-store.js +562 -0
- package/dist/tools/terminal-output-store.js.map +1 -0
- package/dist/tools/terminal-output-store.test.d.ts +1 -0
- package/dist/tools/terminal-output-store.test.js +364 -0
- package/dist/tools/terminal-output-store.test.js.map +1 -0
- package/dist/tools/tool.d.ts +5 -0
- package/dist/tools/tool.js.map +1 -1
- package/dist/types/events.d.ts +1 -0
- package/dist/types/messages.d.ts +1 -0
- package/dist/web/agent-content-detail.d.ts +78 -0
- package/dist/web/agent-content-detail.js +495 -0
- package/dist/web/agent-content-detail.js.map +1 -0
- package/dist/web/agent-content-detail.test.d.ts +1 -0
- package/dist/web/agent-content-detail.test.js +307 -0
- package/dist/web/agent-content-detail.test.js.map +1 -0
- package/dist/web/agent-parent-messages.test.d.ts +1 -0
- package/dist/web/agent-parent-messages.test.js +58 -0
- package/dist/web/agent-parent-messages.test.js.map +1 -0
- package/dist/web/agent-tool-payload-security.test.d.ts +1 -0
- package/dist/web/agent-tool-payload-security.test.js +120 -0
- package/dist/web/agent-tool-payload-security.test.js.map +1 -0
- package/dist/web/index.d.ts +213 -9
- package/dist/web/index.js +260 -108
- package/dist/web/index.js.map +1 -1
- package/dist/web/smoke-agent-content-http.d.ts +1 -0
- package/dist/web/smoke-agent-content-http.js +446 -0
- package/dist/web/smoke-agent-content-http.js.map +1 -0
- package/dist/web/smoke-status-semantics.d.ts +1 -0
- package/dist/web/smoke-status-semantics.js +90 -0
- package/dist/web/smoke-status-semantics.js.map +1 -0
- package/dist/web/smoke-task-session-entrypoints.d.ts +1 -0
- package/dist/web/smoke-task-session-entrypoints.js +96 -0
- package/dist/web/smoke-task-session-entrypoints.js.map +1 -0
- package/dist/web/smoke-terminal-output-http.d.ts +1 -0
- package/dist/web/smoke-terminal-output-http.js +372 -0
- package/dist/web/smoke-terminal-output-http.js.map +1 -0
- package/dist/web/smoke-tool-call-detail.d.ts +1 -0
- package/dist/web/smoke-tool-call-detail.js +106 -0
- package/dist/web/smoke-tool-call-detail.js.map +1 -0
- package/dist/web/smoke-tool-call-http.d.ts +1 -0
- package/dist/web/smoke-tool-call-http.js +100 -0
- package/dist/web/smoke-tool-call-http.js.map +1 -0
- package/dist/web/smoke-tool-detail-fields-http.d.ts +1 -0
- package/dist/web/smoke-tool-detail-fields-http.js +121 -0
- package/dist/web/smoke-tool-detail-fields-http.js.map +1 -0
- package/dist/web/smoke-web-agent-tasks.d.ts +1 -0
- package/dist/web/smoke-web-agent-tasks.js +50 -0
- package/dist/web/smoke-web-agent-tasks.js.map +1 -0
- package/dist/web/smoke-web-terminal-tasks.js +126 -76
- package/dist/web/smoke-web-terminal-tasks.js.map +1 -1
- package/dist/web/status-semantics.d.ts +11 -0
- package/dist/web/status-semantics.js +59 -0
- package/dist/web/status-semantics.js.map +1 -0
- package/dist/web/terminal-presentation.d.ts +15 -0
- package/dist/web/terminal-presentation.js +61 -0
- package/dist/web/terminal-presentation.js.map +1 -0
- package/dist/web/terminal-presentation.test.d.ts +1 -0
- package/dist/web/terminal-presentation.test.js +33 -0
- package/dist/web/terminal-presentation.test.js.map +1 -0
- package/dist/web/tool-call-detail.d.ts +40 -0
- package/dist/web/tool-call-detail.js +167 -0
- package/dist/web/tool-call-detail.js.map +1 -0
- package/dist/web/tool-detail-fields.d.ts +59 -0
- package/dist/web/tool-detail-fields.js +119 -0
- package/dist/web/tool-detail-fields.js.map +1 -0
- package/dist/web/tool-detail-fields.test.d.ts +1 -0
- package/dist/web/tool-detail-fields.test.js +121 -0
- package/dist/web/tool-detail-fields.test.js.map +1 -0
- package/package.json +90 -90
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import { InMemorySecretRedactionRegistry } from '../secrets/secret-redaction.js';
|
|
2
|
+
import { runToolUseToMessages } from '../tools/run-tool-use.js';
|
|
3
|
+
import { ToolRegistry } from '../tools/registry.js';
|
|
4
|
+
import { InMemoryAppState } from '../app/app-state.js';
|
|
5
|
+
import { readFileTool } from '../tools/builtins/filesystem-tools.js';
|
|
6
|
+
import { editTool } from '../tools/builtins/edit-tool.js';
|
|
7
|
+
import { createSubagentTools } from '../tasks/subagent-tools.js';
|
|
8
|
+
import { TaskStore } from '../tasks/task-store.js';
|
|
9
|
+
import assert from 'node:assert/strict';
|
|
10
|
+
import fs from 'node:fs/promises';
|
|
11
|
+
import os from 'node:os';
|
|
12
|
+
import path from 'node:path';
|
|
13
|
+
import { readToolCallDetail, redactToolDetail, allowToolDetailRequest } from './tool-call-detail.js';
|
|
14
|
+
import { SessionStore } from '../session/session-store.js';
|
|
15
|
+
import { FileToolResultMemory } from '../session/tool-result-memory.js';
|
|
16
|
+
import { createToolResultMessage } from '../types/messages.js';
|
|
17
|
+
import { restoreWebHistoryLines, WebRepl } from './index.js';
|
|
18
|
+
const dir = await fs.mkdtemp(path.join(os.tmpdir(), 'obs01-'));
|
|
19
|
+
let checks = 0;
|
|
20
|
+
const check = (v) => { assert.ok(v); checks++; };
|
|
21
|
+
try {
|
|
22
|
+
const request = { id: 'call-one', name: 'file_read', input: { path: 'missing.txt', offset: 0, token: 'INPUT_SECRET' } };
|
|
23
|
+
const use = { id: 'use-message', role: 'assistant', createdAt: '', blocks: [{ type: 'tool_use', ...request }] };
|
|
24
|
+
const entry = (message) => ({ type: 'message', message });
|
|
25
|
+
const options = { sessionId: 's1', expectedSessionId: 's1', sessionDir: dir, toolUseId: request.id };
|
|
26
|
+
for (const error of ['ENOENT: missing.txt', 'oldString not found', 'input.path must be string', 'Unknown agent target: nobody']) {
|
|
27
|
+
const result = createToolResultMessage(request, false, { error });
|
|
28
|
+
const entries = [entry(use), entry(result)];
|
|
29
|
+
const detail = await readToolCallDetail({ ...options, entries });
|
|
30
|
+
check(detail?.error.text === error);
|
|
31
|
+
check(detail?.input.text.includes('missing.txt') && !detail?.input.text.includes('INPUT_SECRET'));
|
|
32
|
+
const lines = restoreWebHistoryLines({ engine: { getDisplayEntries: () => entries } });
|
|
33
|
+
check(lines.some(line => line.kind === 'error' && line.toolUseId === request.id && line.toolError === error));
|
|
34
|
+
}
|
|
35
|
+
const tools = new ToolRegistry();
|
|
36
|
+
tools.register(readFileTool);
|
|
37
|
+
tools.register(editTool);
|
|
38
|
+
for (const tool of createSubagentTools(new TaskStore()))
|
|
39
|
+
tools.register(tool);
|
|
40
|
+
await fs.writeFile(path.join(dir, 'edit.txt'), 'unchanged');
|
|
41
|
+
const context = { emit: () => { }, agentId: 'test', tools, appState: new InMemoryAppState('test', dir), session: { sessionId: 's1', sessionDir: dir } };
|
|
42
|
+
for (const actual of [
|
|
43
|
+
{ id: 'real-read', name: 'file_read', input: { path: path.join(dir, 'absent.txt') } },
|
|
44
|
+
{ id: 'real-edit', name: 'file_edit', input: { path: path.join(dir, 'edit.txt'), oldString: 'NOT_FOUND', newString: 'new' } },
|
|
45
|
+
{ id: 'real-schema', name: 'file_read', input: { path: 123 } },
|
|
46
|
+
{ id: 'real-agent', name: 'subagent_message', input: { target: 'nonexistent', message: 'hello' } }
|
|
47
|
+
]) {
|
|
48
|
+
const messages = await runToolUseToMessages(actual, context);
|
|
49
|
+
const actualUse = { ...use, id: actual.id + '-input', blocks: [{ type: 'tool_use', ...actual }] };
|
|
50
|
+
const detail = await readToolCallDetail({ ...options, toolUseId: actual.id, entries: [entry(actualUse), ...messages.map(entry)] });
|
|
51
|
+
check(detail?.ok === false && !!detail.error.text && detail.error.text !== '未提供错误原因');
|
|
52
|
+
console.log(actual.name + ' actual failure: ' + detail?.error.text);
|
|
53
|
+
}
|
|
54
|
+
const registry = new InMemorySecretRedactionRegistry();
|
|
55
|
+
registry.record('runtime-secret', 'REGISTERED_NOT_IN_ENV');
|
|
56
|
+
const registryResult = await readToolCallDetail({ ...options, redact: value => registry.redact(value), entries: [entry(use), entry(createToolResultMessage(request, true, { content: 'REGISTERED_NOT_IN_ENV', lastText: 'HIDDEN_CAMEL' }))] });
|
|
57
|
+
check(!JSON.stringify(registryResult).includes('REGISTERED_NOT_IN_ENV') && !JSON.stringify(registryResult).includes('HIDDEN_CAMEL'));
|
|
58
|
+
const fake = { runtime: { engine: { snapshot: () => ({ session: { sessionId: 's1' } }), redactDisplayValue: (v) => registry.redact(v), isFastMode: () => false, getAppPrompt: () => ({}) } },
|
|
59
|
+
lines: [{ id: 1, toolError: 'REGISTERED_NOT_IN_ENV' }], backgroundTasks: () => [], terminalTaskHistory: () => [], backgroundSessionRuns: new Map(), pendingDeltaOperations: [], scheduleDeltaFlush: () => { } };
|
|
60
|
+
// Snapshot also needs the existing task-store projection contract.
|
|
61
|
+
Object.assign(fake.runtime, { taskStore: { list: () => [] } });
|
|
62
|
+
const projected = WebRepl.prototype.snapshot.call(fake);
|
|
63
|
+
check(projected.lines[0].toolError === '[secret:runtime-secret]');
|
|
64
|
+
const queue = WebRepl.prototype.queueDeltaOperation;
|
|
65
|
+
queue.call(fake, { type: 'line.append', line: { id: 2, toolError: 'REGISTERED_NOT_IN_ENV' } });
|
|
66
|
+
queue.call(fake, { type: 'line.patch', id: 2, patch: { toolError: 'REGISTERED_NOT_IN_ENV' } });
|
|
67
|
+
check(!JSON.stringify(fake.pendingDeltaOperations).includes('REGISTERED_NOT_IN_ENV'));
|
|
68
|
+
const memory = new FileToolResultMemory({ sessionDir: dir, thresholdChars: 100 });
|
|
69
|
+
const full = { arbitrary: 'REGISTERED_NOT_IN_ENV', content: 'FULL_START\n' + 'x'.repeat(9000) + '\nFULL_END', password: 'OUTPUT_SECRET' };
|
|
70
|
+
const processed = await memory.processToolResult(request.id, full);
|
|
71
|
+
const result = createToolResultMessage(request, true, processed.output);
|
|
72
|
+
const entries = [entry(use), entry(result)];
|
|
73
|
+
const detail = await readToolCallDetail({ ...options, entries });
|
|
74
|
+
const store = await SessionStore.open({ agentId: 'test', rootDir: dir, sessionId: 'persisted' });
|
|
75
|
+
for (const item of entries)
|
|
76
|
+
store.recordMessage(item.message);
|
|
77
|
+
const restored = await SessionStore.open({ agentId: 'test', rootDir: dir, sessionId: 'persisted', resume: true });
|
|
78
|
+
check((await readToolCallDetail({ ...options, entries: restored.getDisplayEntries() }))?.result.text === detail?.result.text);
|
|
79
|
+
check(detail?.result.state === 'complete' && detail.result.text.includes('FULL_END'));
|
|
80
|
+
check(!JSON.stringify(detail).includes('OUTPUT_SECRET'));
|
|
81
|
+
check(!JSON.stringify(await readToolCallDetail({ ...options, entries, redact: value => registry.redact(value) })).includes('REGISTERED_NOT_IN_ENV'));
|
|
82
|
+
check((await readToolCallDetail({ ...options, entries: JSON.parse(JSON.stringify(entries)) }))?.result.text === detail?.result.text);
|
|
83
|
+
check(await readToolCallDetail({ ...options, entries, expectedSessionId: 'other' }) === undefined);
|
|
84
|
+
check(await readToolCallDetail({ ...options, entries, toolUseId: 'other' }) === undefined);
|
|
85
|
+
check(await readToolCallDetail({ ...options, entries, messageId: 'other' }) === undefined);
|
|
86
|
+
check(await readToolCallDetail({ ...options, entries: [...entries, entry(use)] }) === undefined);
|
|
87
|
+
await fs.rm(path.join(dir, 'tool-results'), { recursive: true });
|
|
88
|
+
check((await readToolCallDetail({ ...options, entries }))?.result.state === 'unavailable');
|
|
89
|
+
const malicious = createToolResultMessage(request, true, '<persisted-output>\nFull output saved to: ' + path.join(dir, '../private.txt') + '\n');
|
|
90
|
+
check((await readToolCallDetail({ ...options, entries: [entry(use), entry(malicious)] }))?.result.state === 'unavailable');
|
|
91
|
+
for (const output of [0, false, [], '', null])
|
|
92
|
+
check((await readToolCallDetail({ ...options, entries: [entry(createToolResultMessage(request, true, output))] }))?.result.state === 'complete');
|
|
93
|
+
check((await readToolCallDetail({ ...options, entries: [entry(createToolResultMessage(request, true, { truncated: true, content: 'preview' }))] }))?.result.state === 'truncated');
|
|
94
|
+
check((await readToolCallDetail({ ...options, entries: [entry(result)] }))?.input.state === 'missing');
|
|
95
|
+
check(!allowToolDetailRequest('https://evil.example', 'localhost:123', 'cross-site'));
|
|
96
|
+
check(allowToolDetailRequest('http://localhost:123', 'localhost:123', 'same-origin'));
|
|
97
|
+
const redacted = JSON.stringify(redactToolDetail({ config: { a: 'PRIVATE_CONFIG' }, thinking: 'HIDDEN', nested: { apiKey: 'KEY' }, error: 'Authorization: Bearer abc123 password=abcd sk-very-secret-key' }));
|
|
98
|
+
for (const secret of ['PRIVATE_CONFIG', 'HIDDEN', 'abc123', 'abcd', 'sk-very-secret-key'])
|
|
99
|
+
check(!redacted.includes(secret));
|
|
100
|
+
check(await readToolCallDetail({ ...options, entries: [entry({ ...use, blocks: [{ type: 'tool_use', ...request, name: 'secret_get' }] })] }) === undefined);
|
|
101
|
+
console.log(`OBS-01 service smoke passed: ${checks} assertions`);
|
|
102
|
+
}
|
|
103
|
+
finally {
|
|
104
|
+
await fs.rm(dir, { recursive: true, force: true });
|
|
105
|
+
}
|
|
106
|
+
//# sourceMappingURL=smoke-tool-call-detail.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"smoke-tool-call-detail.js","sourceRoot":"","sources":["../../src/web/smoke-tool-call-detail.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
// Real Node HTTP route + WebRepl detail + real disk storage; no model/network provider.
|
|
2
|
+
import assert from 'node:assert/strict';
|
|
3
|
+
import http from 'node:http';
|
|
4
|
+
import fs from 'node:fs/promises';
|
|
5
|
+
import os from 'node:os';
|
|
6
|
+
import path from 'node:path';
|
|
7
|
+
import { runWebServer, WebRepl, restoreWebHistoryLines } from './index.js';
|
|
8
|
+
import { FileToolResultMemory } from '../session/tool-result-memory.js';
|
|
9
|
+
import { createToolResultMessage } from '../types/messages.js';
|
|
10
|
+
const root = await fs.mkdtemp(path.join(os.tmpdir(), 'obs01-http-'));
|
|
11
|
+
const sessions = new Map();
|
|
12
|
+
for (const id of ['A', 'B']) {
|
|
13
|
+
const dir = path.join(root, id);
|
|
14
|
+
await fs.mkdir(dir);
|
|
15
|
+
const req = { id: 'same-call', name: 'file_read', input: { path: `${id}.txt` } };
|
|
16
|
+
const memory = new FileToolResultMemory({ sessionDir: dir, thresholdChars: 20 });
|
|
17
|
+
const output = await memory.processToolResult(req.id, { content: `SESSION_${id}_ONLY` + 'x'.repeat(100) });
|
|
18
|
+
sessions.set(id, { dir, entries: [{ type: 'message', message: { id: `use-${id}`, role: 'assistant', createdAt: '', blocks: [{ type: 'tool_use', ...req }] } }, { type: 'message', message: { ...createToolResultMessage(req, true, output.output), id: `result-${id}` } }] });
|
|
19
|
+
}
|
|
20
|
+
let server;
|
|
21
|
+
const original = http.createServer;
|
|
22
|
+
const probe = original();
|
|
23
|
+
await new Promise(r => probe.listen(0, "127.0.0.1", r));
|
|
24
|
+
const probeAddress = probe.address();
|
|
25
|
+
assert.ok(probeAddress && typeof probeAddress === "object");
|
|
26
|
+
const port = probeAddress.port;
|
|
27
|
+
await new Promise(r => probe.close(() => r()));
|
|
28
|
+
// Capture the real server solely to close it after running its private production route.
|
|
29
|
+
http.createServer = (...args) => { server = original(...args); return server; };
|
|
30
|
+
let executions = 0;
|
|
31
|
+
try {
|
|
32
|
+
await runWebServer(['--host', '127.0.0.1', '--port', String(port)], {
|
|
33
|
+
createRuntime: async (options) => ({ sessionId: options?.sessionId }),
|
|
34
|
+
createRepl: runtime => {
|
|
35
|
+
const id = runtime.sessionId;
|
|
36
|
+
const data = sessions.get(id);
|
|
37
|
+
const fake = { runtime: { engine: { snapshot: () => ({ session: { sessionId: id, sessionDir: data?.dir } }), getDisplayEntries: () => data?.entries ?? [], redactDisplayValue: (v) => v } }, toolCallDetail: WebRepl.prototype.toolCallDetail, submit: () => { executions++; throw new Error('must not execute'); } };
|
|
38
|
+
return fake;
|
|
39
|
+
}
|
|
40
|
+
});
|
|
41
|
+
const address = server.address();
|
|
42
|
+
assert.ok(address && typeof address === 'object');
|
|
43
|
+
const base = `http://127.0.0.1:${address.port}`;
|
|
44
|
+
const url = (s, m = '') => `${base}/api/tool-call-detail?sessionId=${s}&toolUseId=same-call${m ? '&messageId=' + m : ''}`;
|
|
45
|
+
let count = 0;
|
|
46
|
+
const check = (v) => { assert.ok(v); count++; };
|
|
47
|
+
for (const id of ['A', 'B']) {
|
|
48
|
+
const r = await fetch(url(id));
|
|
49
|
+
check(r.status === 200);
|
|
50
|
+
check(r.headers.get('cache-control') === 'no-store');
|
|
51
|
+
const body = await r.json();
|
|
52
|
+
check(body.sessionId === id);
|
|
53
|
+
check(body.result.text.includes(`SESSION_${id}_ONLY`));
|
|
54
|
+
check(!body.result.text.includes(`SESSION_${id === 'A' ? 'B' : 'A'}_ONLY`));
|
|
55
|
+
}
|
|
56
|
+
// Agent source provenance must hold at the ordinary-call HTTP boundary too.
|
|
57
|
+
for (const name of ['subagent_run', 'subagent_get', 'subagent_output']) {
|
|
58
|
+
const request = { id: `legacy-${name}`, name, input: { task_id: 'legacy-task' } };
|
|
59
|
+
const legacy = name === 'subagent_output'
|
|
60
|
+
? '<retrieval_status>ready</retrieval_status>\n<task_id>legacy-task</task_id>\n<task_type>agent</task_type>\n<status>completed</status>\n<run_generation>2</run_generation>\n<pending_messages>0</pending_messages>\n<requires_resume>false</requires_resume>\n<agent_id>legacy-agent</agent_id>\n<output>PRIVATE_LEGACY_REASONING</output>'
|
|
61
|
+
: { task_id: 'legacy-task', run_generation: 2, status: 'completed', result: { content: 'PRIVATE_LEGACY_REASONING' }, progress: { last_text: 'PRIVATE_LEGACY_PROGRESS' } };
|
|
62
|
+
sessions.get('A').entries.push({ type: 'message', message: createToolResultMessage(request, true, legacy) });
|
|
63
|
+
const r = await fetch(`${base}/api/tool-call-detail?sessionId=A&toolUseId=${request.id}`);
|
|
64
|
+
check(r.status === 200);
|
|
65
|
+
const body = await r.json();
|
|
66
|
+
check(!JSON.stringify(body).includes('PRIVATE_LEGACY_'));
|
|
67
|
+
check(body.result.state === 'unavailable');
|
|
68
|
+
check(body.result.text.includes('legacy-task') && body.result.text.includes('2'));
|
|
69
|
+
const lines = restoreWebHistoryLines({ engine: { getDisplayEntries: () => sessions.get('A').entries } });
|
|
70
|
+
check(!JSON.stringify(lines).includes('PRIVATE_LEGACY_'));
|
|
71
|
+
}
|
|
72
|
+
// Windows junction is an actual filesystem symlink/reparse point, no admin privilege needed.
|
|
73
|
+
const a = sessions.get('A');
|
|
74
|
+
await fs.rm(path.join(a.dir, 'tool-results'), { recursive: true });
|
|
75
|
+
await fs.symlink(path.join(sessions.get('B').dir, 'tool-results'), path.join(a.dir, 'tool-results'), 'junction');
|
|
76
|
+
check((await fs.lstat(path.join(a.dir, 'tool-results'))).isSymbolicLink());
|
|
77
|
+
const attack = await (await fetch(url('A'))).json();
|
|
78
|
+
check(attack.result.state === 'unavailable');
|
|
79
|
+
check(!attack.result.text.includes('SESSION_B_ONLY'));
|
|
80
|
+
await fs.unlink(path.join(a.dir, 'tool-results'));
|
|
81
|
+
// Same caller-selected session cannot request the other session's result-message identity.
|
|
82
|
+
const denied = await fetch(url('A', 'result-B'));
|
|
83
|
+
console.log('Actual cross-session status:', denied.status);
|
|
84
|
+
check(denied.status === 404);
|
|
85
|
+
check(!(await denied.text()).includes('SESSION_B_ONLY'));
|
|
86
|
+
check((await fetch(url('absent'))).status === 404);
|
|
87
|
+
check((await fetch(url('A'), { headers: { Origin: 'https://evil.invalid', 'Sec-Fetch-Site': 'cross-site' } })).status === 403);
|
|
88
|
+
check((await fetch(url('A'), { method: 'POST' })).status === 404);
|
|
89
|
+
check(executions === 0);
|
|
90
|
+
console.log(`OBS-01 real HTTP passed: ${count} assertions; GET read-only, 403/404, two runtime session roots, cross-session message refusal, real junction escape refused`);
|
|
91
|
+
}
|
|
92
|
+
finally {
|
|
93
|
+
http.createServer = original;
|
|
94
|
+
server?.closeAllConnections();
|
|
95
|
+
await new Promise(resolve => server ? server.close(() => resolve()) : resolve());
|
|
96
|
+
// Never recursively follow the test junction on failure.
|
|
97
|
+
await fs.unlink(path.join(root, 'A', 'tool-results')).catch(() => { });
|
|
98
|
+
await fs.rm(root, { recursive: true, force: true });
|
|
99
|
+
}
|
|
100
|
+
//# sourceMappingURL=smoke-tool-call-http.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"smoke-tool-call-http.js","sourceRoot":"","sources":["../../src/web/smoke-tool-call-http.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
// Real Node HTTP route + WebRepl detail + real disk storage; no model/network provider.
|
|
2
|
+
import assert from 'node:assert/strict';
|
|
3
|
+
import http from 'node:http';
|
|
4
|
+
import fs from 'node:fs/promises';
|
|
5
|
+
import os from 'node:os';
|
|
6
|
+
import path from 'node:path';
|
|
7
|
+
import { runWebServer, WebRepl } from './index.js';
|
|
8
|
+
import { FileToolResultMemory } from '../session/tool-result-memory.js';
|
|
9
|
+
import { createToolResultMessage } from '../types/messages.js';
|
|
10
|
+
const root = await fs.mkdtemp(path.join(os.tmpdir(), 'obs06-http-'));
|
|
11
|
+
const sessions = new Map();
|
|
12
|
+
for (const id of ['A', 'B']) {
|
|
13
|
+
const dir = path.join(root, id);
|
|
14
|
+
await fs.mkdir(dir);
|
|
15
|
+
const req = { id: 'same-call', name: 'file_read', input: { path: `${id}.txt`, offset: 0, limit: 0, description: 'FULL PURPOSE ' + id } };
|
|
16
|
+
const memory = new FileToolResultMemory({ sessionDir: dir, thresholdChars: 20 });
|
|
17
|
+
const output = await memory.processToolResult(req.id, { path: path.join(dir, `${id}.txt`), content: `SESSION_${id}_ONLY` + 'x'.repeat(100) });
|
|
18
|
+
sessions.set(id, { dir, entries: [{ type: 'message', message: { id: `use-${id}`, role: 'assistant', createdAt: '', blocks: [{ type: 'tool_use', ...req }] } }, { type: 'message', message: { ...createToolResultMessage(req, true, output.output), id: `result-${id}` } }] });
|
|
19
|
+
}
|
|
20
|
+
let server;
|
|
21
|
+
const original = http.createServer;
|
|
22
|
+
const probe = original();
|
|
23
|
+
await new Promise(r => probe.listen(0, "127.0.0.1", r));
|
|
24
|
+
const probeAddress = probe.address();
|
|
25
|
+
assert.ok(probeAddress && typeof probeAddress === "object");
|
|
26
|
+
const port = probeAddress.port;
|
|
27
|
+
await new Promise(r => probe.close(() => r()));
|
|
28
|
+
// Capture the real server solely to close it after running its private production route.
|
|
29
|
+
http.createServer = (...args) => { server = original(...args); return server; };
|
|
30
|
+
let executions = 0;
|
|
31
|
+
try {
|
|
32
|
+
await runWebServer(['--host', '127.0.0.1', '--port', String(port)], {
|
|
33
|
+
createRuntime: async (options) => ({ sessionId: options?.sessionId }),
|
|
34
|
+
createRepl: runtime => {
|
|
35
|
+
const id = runtime.sessionId;
|
|
36
|
+
const data = sessions.get(id);
|
|
37
|
+
const fake = { runtime: { engine: { snapshot: () => ({ session: { sessionId: id, sessionDir: data?.dir } }), getDisplayEntries: () => data?.entries ?? [], redactDisplayValue: (v) => v } }, toolCallDetail: WebRepl.prototype.toolCallDetail, submit: () => { executions++; throw new Error('must not execute'); } };
|
|
38
|
+
return fake;
|
|
39
|
+
}
|
|
40
|
+
});
|
|
41
|
+
const address = server.address();
|
|
42
|
+
assert.ok(address && typeof address === 'object');
|
|
43
|
+
const base = `http://127.0.0.1:${address.port}`;
|
|
44
|
+
const url = (s, m = '') => `${base}/api/tool-call-detail?sessionId=${s}&toolUseId=same-call${m ? '&messageId=' + m : ''}`;
|
|
45
|
+
let count = 0;
|
|
46
|
+
const check = (v) => { assert.ok(v); count++; };
|
|
47
|
+
for (const id of ['A', 'B']) {
|
|
48
|
+
const r = await fetch(url(id));
|
|
49
|
+
check(r.status === 200);
|
|
50
|
+
check(r.headers.get('cache-control') === 'no-store');
|
|
51
|
+
const body = await r.json();
|
|
52
|
+
check(body.sessionId === id);
|
|
53
|
+
check(body.fields.purpose.value === 'FULL PURPOSE ' + id);
|
|
54
|
+
check(body.fields.actualPath.copyValue === path.join(sessions.get(id).dir, `${id}.txt`));
|
|
55
|
+
check(body.fields.keyParameters.find((p) => p.key === 'offset').value === 0);
|
|
56
|
+
check(body.result.text.includes(`SESSION_${id}_ONLY`));
|
|
57
|
+
check(!body.result.text.includes(`SESSION_${id === 'A' ? 'B' : 'A'}_ONLY`));
|
|
58
|
+
}
|
|
59
|
+
// Exercise real production route classification for non-file contracts and old records.
|
|
60
|
+
const data = sessions.get('A');
|
|
61
|
+
const cases = [
|
|
62
|
+
{ name: 'web_search', input: { query: 'q', provider: 'openai', includeDomains: [], startPublishedDate: '2026-01-01' }, output: { provider: 'exa', results: [] } },
|
|
63
|
+
{ name: 'file_edit', input: { path: 'relative', oldString: '', newString: 'line1\nline2', replaceAll: false }, output: { path: path.join(data.dir, 'real.txt') } },
|
|
64
|
+
{ name: 'subagent_message', input: { target: 'worker', message: 'LONG_BODY_'.repeat(3000) }, output: { task_id: 'resolved-task', run_generation: 0 } },
|
|
65
|
+
{ name: 'file_read', input: undefined, output: { truncated: true, path: path.join(data.dir, 'preview.txt') } },
|
|
66
|
+
];
|
|
67
|
+
for (const [i, c] of cases.entries()) {
|
|
68
|
+
const req = { id: 'fields-' + i, name: c.name, input: c.input };
|
|
69
|
+
data.entries.push({ type: 'message', message: { id: 'use-fields-' + i, role: 'assistant', createdAt: '', blocks: [{ type: 'tool_use', ...req }] } }, { type: 'message', message: createToolResultMessage(req, true, c.output) });
|
|
70
|
+
const r = await fetch(`${base}/api/tool-call-detail?sessionId=A&toolUseId=${req.id}`);
|
|
71
|
+
check(r.status === 200);
|
|
72
|
+
const d = await r.json();
|
|
73
|
+
const f = d.fields;
|
|
74
|
+
if (i === 0) {
|
|
75
|
+
check(f.actualProvider.value === 'exa');
|
|
76
|
+
check(f.result.empty);
|
|
77
|
+
check(f.keyParameters.find((p) => p.key === 'excludeDomains').state === 'unspecified');
|
|
78
|
+
}
|
|
79
|
+
if (i === 1) {
|
|
80
|
+
check(f.actualPath.copyValue === c.output.path);
|
|
81
|
+
check(f.keyParameters.find((p) => p.key === 'replaceAll').value === false);
|
|
82
|
+
}
|
|
83
|
+
if (i === 2) {
|
|
84
|
+
check(f.object.value === 'resolved-task');
|
|
85
|
+
check(f.keyParameters.find((p) => p.key === 'message').value === c.input.message);
|
|
86
|
+
}
|
|
87
|
+
if (i === 3) {
|
|
88
|
+
check(f.input.completeness === 'missing');
|
|
89
|
+
check(f.actualPath.copyValue === undefined);
|
|
90
|
+
check(f.actualPath.completeness === 'truncated');
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
// Windows junction is an actual filesystem symlink/reparse point, no admin privilege needed.
|
|
94
|
+
const a = sessions.get('A');
|
|
95
|
+
await fs.rm(path.join(a.dir, 'tool-results'), { recursive: true });
|
|
96
|
+
await fs.symlink(path.join(sessions.get('B').dir, 'tool-results'), path.join(a.dir, 'tool-results'), 'junction');
|
|
97
|
+
check((await fs.lstat(path.join(a.dir, 'tool-results'))).isSymbolicLink());
|
|
98
|
+
const attack = await (await fetch(url('A'))).json();
|
|
99
|
+
check(attack.result.state === 'unavailable');
|
|
100
|
+
check(!attack.result.text.includes('SESSION_B_ONLY'));
|
|
101
|
+
await fs.unlink(path.join(a.dir, 'tool-results'));
|
|
102
|
+
// Same caller-selected session cannot request the other session's result-message identity.
|
|
103
|
+
const denied = await fetch(url('A', 'result-B'));
|
|
104
|
+
console.log('Actual cross-session status:', denied.status);
|
|
105
|
+
check(denied.status === 404);
|
|
106
|
+
check(!(await denied.text()).includes('SESSION_B_ONLY'));
|
|
107
|
+
check((await fetch(url('absent'))).status === 404);
|
|
108
|
+
check((await fetch(url('A'), { headers: { Origin: 'https://evil.invalid', 'Sec-Fetch-Site': 'cross-site' } })).status === 403);
|
|
109
|
+
check((await fetch(url('A'), { method: 'POST' })).status === 404);
|
|
110
|
+
check(executions === 0);
|
|
111
|
+
console.log(`OBS-06 real HTTP fields passed: ${count} assertions; GET read-only, 403/404, two runtime session roots, cross-session message refusal, real junction escape refused`);
|
|
112
|
+
}
|
|
113
|
+
finally {
|
|
114
|
+
http.createServer = original;
|
|
115
|
+
server?.closeAllConnections();
|
|
116
|
+
await new Promise(resolve => server ? server.close(() => resolve()) : resolve());
|
|
117
|
+
// Never recursively follow the test junction on failure.
|
|
118
|
+
await fs.unlink(path.join(root, 'A', 'tool-results')).catch(() => { });
|
|
119
|
+
await fs.rm(root, { recursive: true, force: true });
|
|
120
|
+
}
|
|
121
|
+
//# sourceMappingURL=smoke-tool-detail-fields-http.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"smoke-tool-detail-fields-http.js","sourceRoot":"","sources":["../../src/web/smoke-tool-detail-fields-http.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import assert from 'node:assert/strict';
|
|
2
|
+
import { createLocalAgentTask } from '../agents/local-agent-task.js';
|
|
3
|
+
import { WebRepl } from './index.js';
|
|
4
|
+
const task = createLocalAgentTask({ taskId: 'task_ui', agentId: 'agent_ui', description: 'UI regression', prompt: 'private prompt' });
|
|
5
|
+
task.status = 'running';
|
|
6
|
+
task.runGeneration = 2;
|
|
7
|
+
const result = { agent_id: task.agentId, agent_type: 'general', content: 'old report', total_duration_ms: 0, total_tool_use_count: 0, usage: { secret: 'private usage' } };
|
|
8
|
+
task.result = result;
|
|
9
|
+
task.runHistory = [{ runGeneration: 1, status: 'completed', result, progress: task.progress, archivedAt: new Date().toISOString() }];
|
|
10
|
+
const tasks = [task];
|
|
11
|
+
const runtime = {
|
|
12
|
+
taskStore: { list: () => tasks, subscribe: () => () => undefined, isTerminal: (value) => ['completed', 'failed', 'killed'].includes(value.status) },
|
|
13
|
+
execProcessManager: { list: () => [], subscribe: () => () => undefined, subscribeOutput: () => () => undefined },
|
|
14
|
+
engine: { getDisplayEntries: () => [], getHistoryMessages: () => [], snapshot: () => ({ messages: 0, session: { sessionId: 'ui-smoke' } }), isFastMode: () => false, getAppPrompt: () => ({ hasActivePrompt: false }), onSessionTitleChange: () => () => undefined },
|
|
15
|
+
initialMetrics: {},
|
|
16
|
+
};
|
|
17
|
+
const repl = new WebRepl(runtime);
|
|
18
|
+
const snapshot = () => repl.snapshot();
|
|
19
|
+
let view = snapshot();
|
|
20
|
+
assert.equal(view.backgroundTaskCount, 1);
|
|
21
|
+
assert.equal(view.backgroundTasks[0].runGeneration, 2);
|
|
22
|
+
assert.equal(view.backgroundTasks[0].result, undefined);
|
|
23
|
+
assert.equal(view.backgroundTasks[0].runHistory[0].result.content, 'old report');
|
|
24
|
+
assert.equal(JSON.stringify(view.backgroundTasks).includes('private prompt'), false);
|
|
25
|
+
assert.equal(JSON.stringify(view.backgroundTasks).includes('private usage'), false);
|
|
26
|
+
task.status = 'completed';
|
|
27
|
+
task.result = { ...result, content: 'current report' };
|
|
28
|
+
view = snapshot();
|
|
29
|
+
assert.equal(view.backgroundTaskCount, 0);
|
|
30
|
+
assert.equal(view.agentTaskHistory[0].result.content, 'current report');
|
|
31
|
+
task.result = { ...result, content: 'x'.repeat(10000) };
|
|
32
|
+
task.runGeneration = 6;
|
|
33
|
+
task.runHistory = Array.from({ length: 5 }, (_, i) => ({ runGeneration: i + 1, status: 'completed', result: task.result, progress: task.progress, archivedAt: task.updatedAt }));
|
|
34
|
+
task.messageReceipts = Array.from({ length: 128 }, (_, i) => ({ id: `receipt_${i}`, messageId: `message_${i}`, status: 'delivered', queuedAt: task.createdAt, deliveredAt: task.updatedAt, runGeneration: 6 }));
|
|
35
|
+
task.progress.lastActivity = '2026-01-01T00:00:00.000Z';
|
|
36
|
+
const compact = snapshot().agentTaskHistory[0];
|
|
37
|
+
assert.equal(compact.result.content.length, 1500);
|
|
38
|
+
assert.equal(compact.result.truncated, true);
|
|
39
|
+
assert.equal(compact.runHistory.length, 3);
|
|
40
|
+
assert.equal(compact.runHistory[0].result.content.length, 600);
|
|
41
|
+
assert.equal(compact.runHistory[0].result.truncated, true);
|
|
42
|
+
assert.equal(compact.messageReceipts.length, 20);
|
|
43
|
+
assert.equal(compact.deliveredRetainedThisRun, 128);
|
|
44
|
+
assert.equal(compact.progress.lastActivity, task.progress.lastActivity);
|
|
45
|
+
assert.ok(JSON.stringify(compact).length < 10000);
|
|
46
|
+
for (let i = 0; i < 25; i++)
|
|
47
|
+
tasks.push({ ...task, id: `task_${i}`, taskId: `task_${i}` });
|
|
48
|
+
assert.equal(snapshot().agentTaskHistory.length, 20);
|
|
49
|
+
console.log('web agent tasks smoke ok: active/history split, generation, stale result suppression, bounded projection, no prompt/usage');
|
|
50
|
+
//# sourceMappingURL=smoke-web-agent-tasks.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"smoke-web-agent-tasks.js","sourceRoot":"","sources":["../../src/web/smoke-web-agent-tasks.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,oBAAoB,CAAC;AACxC,OAAO,EAAE,oBAAoB,EAAwB,MAAM,+BAA+B,CAAC;AAC3F,OAAO,EAAE,OAAO,EAAmB,MAAM,YAAY,CAAC;AAEtD,MAAM,IAAI,GAAG,oBAAoB,CAAC,EAAE,MAAM,EAAE,SAAS,EAAE,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,EAAE,gBAAgB,EAAE,CAAC,CAAC;AACtI,IAAI,CAAC,MAAM,GAAG,SAAS,CAAC;AACxB,IAAI,CAAC,aAAa,GAAG,CAAC,CAAC;AACvB,MAAM,MAAM,GAAoB,EAAE,QAAQ,EAAE,IAAI,CAAC,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,OAAO,EAAE,YAAY,EAAE,iBAAiB,EAAE,CAAC,EAAE,oBAAoB,EAAE,CAAC,EAAE,KAAK,EAAE,EAAE,MAAM,EAAE,eAAe,EAAE,EAAE,CAAC;AAC5L,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;AACrB,IAAI,CAAC,UAAU,GAAG,CAAC,EAAE,aAAa,EAAE,CAAC,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,CAAC,QAAQ,EAAE,UAAU,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC;AACrI,MAAM,KAAK,GAAG,CAAC,IAAI,CAAC,CAAC;AACrB,MAAM,OAAO,GAAG;IACd,SAAS,EAAE,EAAE,IAAI,EAAE,GAAG,EAAE,CAAC,KAAK,EAAE,SAAS,EAAE,GAAG,EAAE,CAAC,GAAG,EAAE,CAAC,SAAS,EAAE,UAAU,EAAE,CAAC,KAAkB,EAAE,EAAE,CAAC,CAAC,WAAW,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE;IAChK,kBAAkB,EAAE,EAAE,IAAI,EAAE,GAAG,EAAE,CAAC,EAAE,EAAE,SAAS,EAAE,GAAG,EAAE,CAAC,GAAG,EAAE,CAAC,SAAS,EAAE,eAAe,EAAE,GAAG,EAAE,CAAC,GAAG,EAAE,CAAC,SAAS,EAAE;IAChH,MAAM,EAAE,EAAE,iBAAiB,EAAE,GAAG,EAAE,CAAC,EAAE,EAAE,kBAAkB,EAAE,GAAG,EAAE,CAAC,EAAE,EAAE,QAAQ,EAAE,GAAG,EAAE,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,OAAO,EAAE,EAAE,SAAS,EAAE,UAAU,EAAE,EAAE,CAAC,EAAE,UAAU,EAAE,GAAG,EAAE,CAAC,KAAK,EAAE,YAAY,EAAE,GAAG,EAAE,CAAC,CAAC,EAAE,eAAe,EAAE,KAAK,EAAE,CAAC,EAAE,oBAAoB,EAAE,GAAG,EAAE,CAAC,GAAG,EAAE,CAAC,SAAS,EAAE;IACpQ,cAAc,EAAE,EAAE;CACM,CAAC;AAC3B,MAAM,IAAI,GAAG,IAAI,OAAO,CAAC,OAAO,CAAC,CAAC;AAClC,MAAM,QAAQ,GAAG,GAAG,EAAE,CAAC,IAAI,CAAC,QAAQ,EAAsF,CAAC;AAC3H,IAAI,IAAI,GAAG,QAAQ,EAAE,CAAC;AACtB,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,mBAAmB,EAAE,CAAC,CAAC,CAAC;AAC1C,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,aAAa,EAAE,CAAC,CAAC,CAAC;AACvD,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;AACxD,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC;AACjF,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC,QAAQ,CAAC,gBAAgB,CAAC,EAAE,KAAK,CAAC,CAAC;AACrF,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC,QAAQ,CAAC,eAAe,CAAC,EAAE,KAAK,CAAC,CAAC;AACpF,IAAI,CAAC,MAAM,GAAG,WAAW,CAAC;AAC1B,IAAI,CAAC,MAAM,GAAG,EAAE,GAAG,MAAM,EAAE,OAAO,EAAE,gBAAgB,EAAE,CAAC;AACvD,IAAI,GAAG,QAAQ,EAAE,CAAC;AAClB,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,mBAAmB,EAAE,CAAC,CAAC,CAAC;AAC1C,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,EAAE,gBAAgB,CAAC,CAAC;AACxE,IAAI,CAAC,MAAM,GAAG,EAAE,GAAG,MAAM,EAAE,OAAO,EAAE,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC;AACxD,IAAI,CAAC,aAAa,GAAG,CAAC,CAAC;AACvB,IAAI,CAAC,UAAU,GAAG,KAAK,CAAC,IAAI,CAAC,EAAC,MAAM,EAAE,CAAC,EAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,aAAa,EAAE,CAAC,GAAG,CAAC,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,QAAQ,EAAE,IAAI,CAAC,QAAQ,EAAE,UAAU,EAAE,IAAI,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC;AAC/K,IAAI,CAAC,eAAe,GAAG,KAAK,CAAC,IAAI,CAAC,EAAC,MAAM,EAAE,GAAG,EAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,EAAE,WAAW,CAAC,EAAE,EAAE,SAAS,EAAE,WAAW,CAAC,EAAE,EAAE,MAAM,EAAE,WAAW,EAAE,QAAQ,EAAE,IAAI,CAAC,SAAS,EAAE,WAAW,EAAE,IAAI,CAAC,SAAS,EAAE,aAAa,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;AAC9M,IAAI,CAAC,QAAQ,CAAC,YAAY,GAAG,0BAA0B,CAAC;AACxD,MAAM,OAAO,GAAG,QAAQ,EAAE,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC;AAC/C,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;AAClD,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;AAC7C,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,UAAU,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;AAC3C,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;AAC/D,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;AAC3D,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,eAAe,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;AACjD,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,wBAAwB,EAAE,GAAG,CAAC,CAAC;AACpD,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,YAAY,EAAE,IAAI,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAC;AACxE,MAAM,CAAC,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,MAAM,GAAG,KAAK,CAAC,CAAC;AAClD,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,EAAE;IAAE,KAAK,CAAC,IAAI,CAAC,EAAE,GAAG,IAAI,EAAE,EAAE,EAAE,QAAQ,CAAC,EAAE,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,EAAE,CAAC,CAAC;AAC3F,MAAM,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC,gBAAgB,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;AACrD,OAAO,CAAC,GAAG,CAAC,2HAA2H,CAAC,CAAC"}
|