@zq-silk/yui 2.0.0 → 2.2.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/README.md +4 -0
- package/dist/cli/commandCatalog.js +318 -289
- package/dist/cli/commandDiscovery.js +72 -0
- package/dist/cli/completion.js +22 -227
- package/dist/cli/dynamicCompletion.js +12 -6
- package/dist/cli/invocationAuthority.js +2 -2
- package/dist/cli/invocationRouter.js +18 -7
- package/dist/cli.js +23 -3030
- package/dist/commands/capabilityCommands.js +5 -5
- package/dist/commands/globalRoleCommands.js +2 -1
- package/dist/commands/taskCommands.js +90 -21
- package/dist/commands/taskIntegrationCommands.js +3 -1
- package/dist/commands/taskUpstreamCommands.js +3 -1
- package/dist/context/runContextPack.js +132 -5
- package/dist/context/sourceRunContext.js +4 -2
- package/dist/context/taskContext.js +12 -3
- package/dist/controlPlaneCli.js +3092 -0
- package/dist/controller/fileSchedulerStoreAdapter.js +19 -6
- package/dist/controller/jobControl.js +21 -0
- package/dist/executor/agentExecutor.js +1 -1
- package/dist/executor/effectiveLaunch.js +18 -5
- package/dist/executor/fileRoleLaunchPlanner.js +15 -19
- package/dist/integration/gitIntegrationService.js +50 -15
- package/dist/kernel/accessAssessment.js +1 -0
- package/dist/kernel/builtinCapabilities.js +28 -1
- package/dist/kernel/capabilityRegistry.js +64 -19
- package/dist/message/messageContinuation.js +7 -2
- package/dist/nativeAgent/agent.js +275 -0
- package/dist/nativeAgent/cliDemo.js +37 -0
- package/dist/nativeAgent/codingTools.js +11 -0
- package/dist/nativeAgent/commandTool.js +215 -0
- package/dist/nativeAgent/compactionDemo.js +158 -0
- package/dist/nativeAgent/composition.js +71 -0
- package/dist/nativeAgent/context/budget.js +44 -0
- package/dist/nativeAgent/context/index.js +339 -0
- package/dist/nativeAgent/context/providerCompressor.js +103 -0
- package/dist/nativeAgent/contracts.js +1 -0
- package/dist/nativeAgent/demo.js +40 -0
- package/dist/nativeAgent/evaluation/cases.js +38 -0
- package/dist/nativeAgent/evaluation/checks.js +91 -0
- package/dist/nativeAgent/evaluation/demo.js +19 -0
- package/dist/nativeAgent/evaluation/files.js +54 -0
- package/dist/nativeAgent/evaluation/fixture.js +36 -0
- package/dist/nativeAgent/evaluation/index.js +239 -0
- package/dist/nativeAgent/executionOwner.js +209 -0
- package/dist/nativeAgent/filePatterns.js +170 -0
- package/dist/nativeAgent/fileToolsSupport.js +202 -0
- package/dist/nativeAgent/index.js +16 -0
- package/dist/nativeAgent/interaction/cli.js +358 -0
- package/dist/nativeAgent/interaction/contracts.js +1 -0
- package/dist/nativeAgent/interaction/index.js +3 -0
- package/dist/nativeAgent/interaction/memoryDemo.js +115 -0
- package/dist/nativeAgent/interaction/renderer.js +34 -0
- package/dist/nativeAgent/localSafety.js +258 -0
- package/dist/nativeAgent/mockProvider.js +43 -0
- package/dist/nativeAgent/model/anthropicMessages.js +204 -0
- package/dist/nativeAgent/model/chatCompletions.js +210 -0
- package/dist/nativeAgent/model/errors.js +47 -0
- package/dist/nativeAgent/model/gateway.js +423 -0
- package/dist/nativeAgent/model/index.js +7 -0
- package/dist/nativeAgent/model/observationAdapter.js +21 -0
- package/dist/nativeAgent/model/protocols.js +19 -0
- package/dist/nativeAgent/model/responses.js +263 -0
- package/dist/nativeAgent/model/types.js +1 -0
- package/dist/nativeAgent/model/wire.js +73 -0
- package/dist/nativeAgent/observability/index.js +220 -0
- package/dist/nativeAgent/product/catalog.js +82 -0
- package/dist/nativeAgent/product/config.js +295 -0
- package/dist/nativeAgent/product/facts.js +30 -0
- package/dist/nativeAgent/product/index.js +62 -0
- package/dist/nativeAgent/product/location.js +44 -0
- package/dist/nativeAgent/product/runtime.js +276 -0
- package/dist/nativeAgent/product/storage.js +49 -0
- package/dist/nativeAgent/product/tools.js +47 -0
- package/dist/nativeAgent/product/transport.js +54 -0
- package/dist/nativeAgent/projectGuidance/index.js +425 -0
- package/dist/nativeAgent/searchTools.js +305 -0
- package/dist/nativeAgent/session/backends.js +293 -0
- package/dist/nativeAgent/session/catalog.js +97 -0
- package/dist/nativeAgent/session/catalogDemo.js +87 -0
- package/dist/nativeAgent/session/contracts.js +1 -0
- package/dist/nativeAgent/session/format.js +269 -0
- package/dist/nativeAgent/session/index.js +5 -0
- package/dist/nativeAgent/session/location.js +36 -0
- package/dist/nativeAgent/session/sqliteFormat.js +134 -0
- package/dist/nativeAgent/session/store.js +248 -0
- package/dist/nativeAgent/textTools.js +293 -0
- package/dist/nativeAgent/toolManager/executor.js +290 -0
- package/dist/nativeAgent/toolManager/index.js +4 -0
- package/dist/nativeAgent/validation.js +95 -0
- package/dist/plugins/pluginService.js +98 -8
- package/dist/resources/projectResourceService.js +23 -1
- package/dist/runtime/managedIdentity.js +6 -0
- package/dist/surface/surfaceContributions.js +3 -0
- package/dist/task/taskAuthority.js +61 -10
- package/dist/web/assets/assetManifest.js +38 -22
- package/dist/web/assets/client/api.js +115 -0
- package/dist/web/assets/client/app.js +615 -862
- package/dist/web/assets/client/components.js +323 -897
- package/dist/web/assets/client/detail.js +333 -0
- package/dist/web/assets/client/dock.js +225 -0
- package/dist/web/assets/client/dom.js +55 -3
- package/dist/web/assets/client/evidence.js +172 -0
- package/dist/web/assets/client/format.js +25 -14
- package/dist/web/assets/client/forms.js +230 -0
- package/dist/web/assets/client/i18n.js +1024 -791
- package/dist/web/assets/client/overview.js +118 -0
- package/dist/web/assets/client/records.js +63 -0
- package/dist/web/assets/client/sections.js +313 -0
- package/dist/web/assets/client/sidebar.js +146 -0
- package/dist/web/assets/client/theme.js +61 -22
- package/dist/web/assets/icons.js +39 -0
- package/dist/web/assets/shell.js +125 -118
- package/dist/web/assets/styles/base.js +41 -0
- package/dist/web/assets/styles/components.js +169 -0
- package/dist/web/assets/styles/layout.js +56 -77
- package/dist/web/assets/styles/markdown.js +16 -24
- package/dist/web/assets/styles/responsive.js +41 -44
- package/dist/web/assets/styles/tokens.js +65 -89
- package/dist/web/assets/styles/views.js +292 -0
- package/dist/web/webServer.js +2 -1
- package/docs/agent-result-consumption.md +16 -0
- package/docs/agent-result-consumption.zh-CN.md +13 -0
- package/docs/examples/agent-offline.mjs +194 -0
- package/docs/native-agent.md +283 -0
- package/docs/release-workflow.md +61 -0
- package/docs/release-workflow.zh-CN.md +46 -0
- package/docs/roles-and-configuration.md +32 -0
- package/docs/roles-and-configuration.zh-CN.md +26 -0
- package/package.json +1 -1
- package/skills/yui-leader/SKILL.md +9 -0
- package/skills/yui-reviewer/SKILL.md +5 -0
- package/skills/yui-runtime/SKILL.md +33 -0
- package/dist/web/assets/client/taskSummary.js +0 -350
- package/dist/web/assets/client/taskSurface.js +0 -616
- package/dist/web/assets/client/view.js +0 -608
- package/dist/web/assets/styles/cards.js +0 -247
- package/dist/web/assets/styles/widgets.js +0 -168
|
@@ -1,5 +1,6 @@
|
|
|
1
|
+
import { hasManagedIdentity } from "../runtime/managedIdentity.js";
|
|
1
2
|
import { usageError } from "../errors/cliError.js";
|
|
2
|
-
import {
|
|
3
|
+
import { currentManagedRuntime } from "../runtime/managedCaller.js";
|
|
3
4
|
const LEADER_ROLE = "leader";
|
|
4
5
|
export function taskActor(environment, taskId) {
|
|
5
6
|
const env = environment ?? {};
|
|
@@ -16,9 +17,7 @@ export function taskActor(environment, taskId) {
|
|
|
16
17
|
return "operator";
|
|
17
18
|
throw usageError("A managed global Session may perform this action only as Operator.");
|
|
18
19
|
}
|
|
19
|
-
if (env
|
|
20
|
-
|| env.YUI_AGENT_ID !== undefined
|
|
21
|
-
|| env[MANAGED_NATIVE_SESSION_ENV] !== undefined) {
|
|
20
|
+
if (hasManagedIdentity(env)) {
|
|
22
21
|
throw usageError("Managed Agent identity is incomplete; refusing to infer user authority.");
|
|
23
22
|
}
|
|
24
23
|
return "user";
|
|
@@ -52,6 +51,62 @@ export function assertTaskDeliveryAuthority(store, environment, taskId) {
|
|
|
52
51
|
}
|
|
53
52
|
return actor;
|
|
54
53
|
}
|
|
54
|
+
/** Project effects consume the current Session's captured scope, never the
|
|
55
|
+
* Role's desired configuration or the mere presence of a writable directory.
|
|
56
|
+
* Task management (including abort/inspection) remains a separate authority. */
|
|
57
|
+
export function assertTaskProjectWriteAuthority(store, environment, taskId, projectId) {
|
|
58
|
+
const actor = assertTaskDeliveryAuthority(store, environment, taskId);
|
|
59
|
+
if (actor !== "leader")
|
|
60
|
+
return actor;
|
|
61
|
+
const caller = currentManagedRuntime(store, environment, taskId, LEADER_ROLE);
|
|
62
|
+
const session = store.getTaskRoleSessionSet(taskId, LEADER_ROLE)?.sessions[caller.agentId];
|
|
63
|
+
const effective = session?.effective;
|
|
64
|
+
const task = store.getTask(taskId);
|
|
65
|
+
const main = store.getTaskWorkspace(taskId);
|
|
66
|
+
const entry = main?.entries.find(entry => entry.projectId === projectId);
|
|
67
|
+
if (task?.status !== "active" || task.executionGate.state !== "enabled"
|
|
68
|
+
|| !task.projectBindings.some(binding => binding.projectId === projectId)
|
|
69
|
+
|| effective?.profileAccess !== "write" || !effective.writeProjectIds.includes(projectId)
|
|
70
|
+
|| main?.owner.type !== "task" || main.owner.taskId !== taskId
|
|
71
|
+
|| effective.workspace.root !== main.root || entry?.access !== "write"
|
|
72
|
+
|| !effective.workspace.entries.some(captured => captured.projectId === projectId
|
|
73
|
+
&& captured.access === "write" && captured.path === entry.path)) {
|
|
74
|
+
throw usageError("Project write requires this Task's current delivery Session with a captured writable Project in its Task-main workspace. Read the Session scope; use formal Session replacement to adopt a new boundary.");
|
|
75
|
+
}
|
|
76
|
+
return actor;
|
|
77
|
+
}
|
|
78
|
+
/** A managed Leader integrates into its captured Task-main, not any branch
|
|
79
|
+
* reachable through the same Git repository. The executor also verifies that
|
|
80
|
+
* this ref is physically checked out here immediately before target effects. */
|
|
81
|
+
export function taskIntegrationTargetCheckout(store, environment, taskId, projectId, targetRef) {
|
|
82
|
+
if (assertTaskProjectWriteAuthority(store, environment, taskId, projectId) !== "leader") {
|
|
83
|
+
return undefined;
|
|
84
|
+
}
|
|
85
|
+
return taskIntegrationSettlementCheckout(store, environment, taskId, projectId, targetRef);
|
|
86
|
+
}
|
|
87
|
+
/** Confirming an already-applied CAS is Task management, not a Project write
|
|
88
|
+
* grant. Keep the current delivery identity and captured target ownership, but
|
|
89
|
+
* do not require or change its declared write scope. Never use this for CAS. */
|
|
90
|
+
export function taskIntegrationSettlementCheckout(store, environment, taskId, projectId, targetRef) {
|
|
91
|
+
if (assertTaskDeliveryAuthority(store, environment, taskId) !== "leader")
|
|
92
|
+
return undefined;
|
|
93
|
+
const task = store.getTask(taskId);
|
|
94
|
+
const main = store.getTaskWorkspace(taskId);
|
|
95
|
+
const entry = main?.entries.find(entry => entry.projectId === projectId);
|
|
96
|
+
const caller = currentManagedRuntime(store, environment, taskId, LEADER_ROLE);
|
|
97
|
+
const effective = store.getTaskRoleSessionSet(taskId, LEADER_ROLE)?.sessions[caller.agentId]?.effective;
|
|
98
|
+
const captured = effective?.workspace.entries.find(entry => entry.projectId === projectId);
|
|
99
|
+
const branchRef = (ref) => ref.startsWith("refs/heads/") ? ref : `refs/heads/${ref}`;
|
|
100
|
+
if (task?.status !== "active" || !task.projectBindings.some(binding => binding.projectId === projectId)
|
|
101
|
+
|| main?.owner.type !== "task" || main.owner.taskId !== taskId
|
|
102
|
+
|| effective?.workspace.root !== main.root || entry?.access !== "write"
|
|
103
|
+
|| captured?.path !== entry.path || entry.branch === undefined || captured.branch === undefined
|
|
104
|
+
|| branchRef(entry.branch) !== branchRef(captured.branch)
|
|
105
|
+
|| branchRef(targetRef) !== branchRef(captured.branch)) {
|
|
106
|
+
throw usageError("Managed Leader Integration target must be its captured Task-main branch and checkout.");
|
|
107
|
+
}
|
|
108
|
+
return entry.path;
|
|
109
|
+
}
|
|
55
110
|
/**
|
|
56
111
|
* Authority for a live steer/interrupt of an exact current native Turn
|
|
57
112
|
* (decision-3 §1/§9, message-5 gap B). The legal evidence is the native
|
|
@@ -86,9 +141,7 @@ export function projectActor(environment) {
|
|
|
86
141
|
return "operator";
|
|
87
142
|
throw usageError("A managed global Session may manage Project Knowledge only as Operator.");
|
|
88
143
|
}
|
|
89
|
-
if (env
|
|
90
|
-
|| env.YUI_AGENT_ID !== undefined
|
|
91
|
-
|| env[MANAGED_NATIVE_SESSION_ENV] !== undefined) {
|
|
144
|
+
if (hasManagedIdentity(env)) {
|
|
92
145
|
throw usageError("Managed Agent identity is incomplete; refusing to infer user authority.");
|
|
93
146
|
}
|
|
94
147
|
return "user";
|
|
@@ -124,9 +177,7 @@ export function resolveJobCaller(environment, taskId) {
|
|
|
124
177
|
nativeSessionId: env.CODEX_THREAD_ID ?? env.YUI_NATIVE_SESSION_ID
|
|
125
178
|
};
|
|
126
179
|
}
|
|
127
|
-
if (env
|
|
128
|
-
|| env.YUI_AGENT_ID !== undefined
|
|
129
|
-
|| env[MANAGED_NATIVE_SESSION_ENV] !== undefined) {
|
|
180
|
+
if (hasManagedIdentity(env)) {
|
|
130
181
|
throw usageError("Managed Agent identity is incomplete; refusing to infer user authority.");
|
|
131
182
|
}
|
|
132
183
|
return { scope: "user" };
|
|
@@ -1,43 +1,59 @@
|
|
|
1
1
|
import { readFileSync } from "node:fs";
|
|
2
2
|
import { createRequire } from "node:module";
|
|
3
|
+
import { API_SCRIPT } from "./client/api.js";
|
|
3
4
|
import { APP_SCRIPT } from "./client/app.js";
|
|
4
5
|
import { COMPONENTS_SCRIPT } from "./client/components.js";
|
|
6
|
+
import { DETAIL_SCRIPT } from "./client/detail.js";
|
|
7
|
+
import { DOCK_SCRIPT } from "./client/dock.js";
|
|
5
8
|
import { DOM_SCRIPT } from "./client/dom.js";
|
|
9
|
+
import { EVIDENCE_SCRIPT } from "./client/evidence.js";
|
|
6
10
|
import { FORMAT_SCRIPT } from "./client/format.js";
|
|
11
|
+
import { FORMS_SCRIPT } from "./client/forms.js";
|
|
7
12
|
import { I18N_SCRIPT } from "./client/i18n.js";
|
|
8
13
|
import { MARKDOWN_SCRIPT } from "./client/markdown.js";
|
|
14
|
+
import { OVERVIEW_SCRIPT } from "./client/overview.js";
|
|
15
|
+
import { RECORDS_SCRIPT } from "./client/records.js";
|
|
16
|
+
import { SECTIONS_SCRIPT } from "./client/sections.js";
|
|
17
|
+
import { SIDEBAR_SCRIPT } from "./client/sidebar.js";
|
|
9
18
|
import { THEME_SCRIPT } from "./client/theme.js";
|
|
10
|
-
import { VIEW_SCRIPT } from "./client/view.js";
|
|
11
|
-
import { TASK_SURFACE_SCRIPT } from "./client/taskSurface.js";
|
|
12
|
-
import { TASK_SUMMARY_SCRIPT } from "./client/taskSummary.js";
|
|
13
19
|
import { DASHBOARD_HTML } from "./shell.js";
|
|
14
20
|
import { FONT_FACE_STYLES } from "./fonts.js";
|
|
15
21
|
import { FONT_WOFF2_BASE64 } from "./fontData.js";
|
|
16
|
-
import {
|
|
22
|
+
import { BASE_STYLES } from "./styles/base.js";
|
|
23
|
+
import { COMPONENT_STYLES } from "./styles/components.js";
|
|
17
24
|
import { LAYOUT_STYLES } from "./styles/layout.js";
|
|
18
25
|
import { MARKDOWN_STYLES } from "./styles/markdown.js";
|
|
19
26
|
import { RESPONSIVE_STYLES } from "./styles/responsive.js";
|
|
20
27
|
import { TOKEN_STYLES } from "./styles/tokens.js";
|
|
21
|
-
import {
|
|
28
|
+
import { VIEW_STYLES } from "./styles/views.js";
|
|
22
29
|
const require = createRequire(import.meta.url);
|
|
30
|
+
const CSS = "text/css; charset=utf-8";
|
|
31
|
+
const JS = "text/javascript; charset=utf-8";
|
|
23
32
|
export const WEB_ASSETS = Object.freeze({
|
|
24
|
-
"/assets/css/
|
|
25
|
-
"/assets/css/
|
|
26
|
-
"/assets/css/
|
|
27
|
-
"/assets/css/
|
|
28
|
-
"/assets/css/
|
|
29
|
-
"/assets/css/
|
|
30
|
-
"/assets/css/
|
|
31
|
-
"/assets/
|
|
32
|
-
"/assets/js/
|
|
33
|
-
"/assets/js/
|
|
34
|
-
"/assets/js/
|
|
35
|
-
"/assets/js/
|
|
36
|
-
"/assets/js/
|
|
37
|
-
"/assets/js/
|
|
38
|
-
"/assets/js/
|
|
39
|
-
"/assets/js/
|
|
40
|
-
"/assets/
|
|
33
|
+
"/assets/css/fonts.css": { contentType: CSS, body: FONT_FACE_STYLES },
|
|
34
|
+
"/assets/css/tokens.css": { contentType: CSS, body: TOKEN_STYLES },
|
|
35
|
+
"/assets/css/base.css": { contentType: CSS, body: BASE_STYLES },
|
|
36
|
+
"/assets/css/layout.css": { contentType: CSS, body: LAYOUT_STYLES },
|
|
37
|
+
"/assets/css/components.css": { contentType: CSS, body: COMPONENT_STYLES },
|
|
38
|
+
"/assets/css/views.css": { contentType: CSS, body: VIEW_STYLES },
|
|
39
|
+
"/assets/css/markdown.css": { contentType: CSS, body: MARKDOWN_STYLES },
|
|
40
|
+
"/assets/css/responsive.css": { contentType: CSS, body: RESPONSIVE_STYLES },
|
|
41
|
+
"/assets/js/dom.js": { contentType: JS, body: DOM_SCRIPT },
|
|
42
|
+
"/assets/js/format.js": { contentType: JS, body: FORMAT_SCRIPT },
|
|
43
|
+
"/assets/js/i18n.js": { contentType: JS, body: I18N_SCRIPT },
|
|
44
|
+
"/assets/js/markdown.js": { contentType: JS, body: MARKDOWN_SCRIPT },
|
|
45
|
+
"/assets/js/theme.js": { contentType: JS, body: THEME_SCRIPT },
|
|
46
|
+
"/assets/js/api.js": { contentType: JS, body: API_SCRIPT },
|
|
47
|
+
"/assets/js/components.js": { contentType: JS, body: COMPONENTS_SCRIPT },
|
|
48
|
+
"/assets/js/records.js": { contentType: JS, body: RECORDS_SCRIPT },
|
|
49
|
+
"/assets/js/forms.js": { contentType: JS, body: FORMS_SCRIPT },
|
|
50
|
+
"/assets/js/evidence.js": { contentType: JS, body: EVIDENCE_SCRIPT },
|
|
51
|
+
"/assets/js/sidebar.js": { contentType: JS, body: SIDEBAR_SCRIPT },
|
|
52
|
+
"/assets/js/overview.js": { contentType: JS, body: OVERVIEW_SCRIPT },
|
|
53
|
+
"/assets/js/sections.js": { contentType: JS, body: SECTIONS_SCRIPT },
|
|
54
|
+
"/assets/js/detail.js": { contentType: JS, body: DETAIL_SCRIPT },
|
|
55
|
+
"/assets/js/dock.js": { contentType: JS, body: DOCK_SCRIPT },
|
|
56
|
+
"/assets/app.js": { contentType: JS, body: APP_SCRIPT },
|
|
41
57
|
...fontAssets(),
|
|
42
58
|
"/assets/vendor/xterm.mjs": vendorAsset("@xterm/xterm/lib/xterm.mjs", "text/javascript; charset=utf-8"),
|
|
43
59
|
"/assets/vendor/addon-fit.mjs": vendorAsset("@xterm/addon-fit/lib/addon-fit.mjs", "text/javascript; charset=utf-8"),
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
export const API_SCRIPT = String.raw `
|
|
2
|
+
// Loopback API client. Every request carries the page token; a write is keyed
|
|
3
|
+
// so an unresolved submission can never be silently replayed from this page.
|
|
4
|
+
const token = document.querySelector('meta[name="yui-web-token"]').content;
|
|
5
|
+
const unresolved = new Set();
|
|
6
|
+
|
|
7
|
+
export function pageToken() { return token; }
|
|
8
|
+
|
|
9
|
+
export async function requestJson(path, options) {
|
|
10
|
+
const response = await fetch(path, {
|
|
11
|
+
...options,
|
|
12
|
+
headers: {
|
|
13
|
+
accept: "application/json",
|
|
14
|
+
"x-yui-web-token": token,
|
|
15
|
+
...(options && options.headers ? options.headers : {})
|
|
16
|
+
}
|
|
17
|
+
});
|
|
18
|
+
if (!response.ok) {
|
|
19
|
+
let message = "HTTP " + response.status;
|
|
20
|
+
let disposition = "unknown";
|
|
21
|
+
try {
|
|
22
|
+
const body = await response.json();
|
|
23
|
+
if (body && body.error) message = body.error;
|
|
24
|
+
if (body && body.disposition === "not-submitted") disposition = "not-submitted";
|
|
25
|
+
} catch {}
|
|
26
|
+
throw Object.assign(new Error(message), { disposition, status: response.status });
|
|
27
|
+
}
|
|
28
|
+
return response.json();
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
function postJson(path, body, signal) {
|
|
32
|
+
return requestJson(path, {
|
|
33
|
+
method: "POST", headers: { "content-type": "application/json" }, body: JSON.stringify(body),
|
|
34
|
+
...(signal ? { signal } : {})
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// A key stays blocked until the server either answers or proves the request
|
|
39
|
+
// was not submitted; an unknown outcome must be inspected, not resent.
|
|
40
|
+
export async function submitMutation(key, path, body) {
|
|
41
|
+
if (unresolved.has(key)) {
|
|
42
|
+
throw Object.assign(new Error("An earlier submission is unresolved; read current facts first."), { disposition: "blocked" });
|
|
43
|
+
}
|
|
44
|
+
unresolved.add(key);
|
|
45
|
+
try {
|
|
46
|
+
const receipt = await postJson(path, body);
|
|
47
|
+
unresolved.delete(key);
|
|
48
|
+
return receipt;
|
|
49
|
+
} catch (error) {
|
|
50
|
+
if (error.disposition === "not-submitted") unresolved.delete(key);
|
|
51
|
+
throw error;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
export function releaseMutation(key) { unresolved.delete(key); }
|
|
56
|
+
|
|
57
|
+
const task = function (taskId) { return "/api/tasks/" + encodeURIComponent(taskId); };
|
|
58
|
+
|
|
59
|
+
export const api = {
|
|
60
|
+
dashboard: function (query) { return requestJson("/api/dashboard?" + query); },
|
|
61
|
+
pageSessions: function (query) {
|
|
62
|
+
return requestJson("/api/dashboard/sessions?" + query, { signal: AbortSignal.timeout(5000) });
|
|
63
|
+
},
|
|
64
|
+
context: function (taskId) { return requestJson(task(taskId) + "/context"); },
|
|
65
|
+
observation: function (taskId) { return requestJson(task(taskId), { signal: AbortSignal.timeout(1500) }); },
|
|
66
|
+
inspect: async function (taskId, ref) {
|
|
67
|
+
const query = new URLSearchParams({ store: ref.store, ref: ref.refId });
|
|
68
|
+
if (ref.digest) query.set("digest", ref.digest);
|
|
69
|
+
let result = await requestJson(task(taskId) + "/inspect?" + query);
|
|
70
|
+
if (!result.contentPage) return result;
|
|
71
|
+
const source = result.contentPage.source;
|
|
72
|
+
const digest = result.contentPage.digest;
|
|
73
|
+
let text = "";
|
|
74
|
+
while (true) {
|
|
75
|
+
const page = result.contentPage;
|
|
76
|
+
if (!page || page.source !== source || page.digest !== digest || page.encoding !== "json"
|
|
77
|
+
|| page.offset !== text.length || typeof page.text !== "string" || !page.text.length) {
|
|
78
|
+
throw new Error("Original read changed or returned an invalid page; refresh its Context reference.");
|
|
79
|
+
}
|
|
80
|
+
text += page.text;
|
|
81
|
+
if (page.complete) return JSON.parse(text);
|
|
82
|
+
if (!page.nextCursor) throw new Error("Original read is incomplete; refresh its Context reference.");
|
|
83
|
+
query.set("cursor", page.nextCursor);
|
|
84
|
+
result = await requestJson(task(taskId) + "/inspect?" + query);
|
|
85
|
+
}
|
|
86
|
+
},
|
|
87
|
+
artifacts: function (taskId) { return requestJson(task(taskId) + "/artifacts"); },
|
|
88
|
+
artifact: function (taskId, path, commit) {
|
|
89
|
+
return requestJson(task(taskId) + "/artifacts?" + new URLSearchParams({ path, commit }));
|
|
90
|
+
},
|
|
91
|
+
evidence: function (taskId) { return requestJson(task(taskId) + "/evidence"); },
|
|
92
|
+
panels: function (taskId) { return requestJson(task(taskId) + "/panels", { signal: AbortSignal.timeout(3000) }); },
|
|
93
|
+
readPanel: function (taskId, ref, input) {
|
|
94
|
+
return postJson(task(taskId) + "/panels", { ref, input }, AbortSignal.timeout(3000));
|
|
95
|
+
},
|
|
96
|
+
sendMessage: function (taskId, body, requestId, intent) {
|
|
97
|
+
return submitMutation(taskId + "/messages", task(taskId) + "/messages",
|
|
98
|
+
{ body, requestId, ...(intent === undefined ? {} : { intent }) });
|
|
99
|
+
},
|
|
100
|
+
control: function (taskId, payload) {
|
|
101
|
+
return submitMutation(taskId + "/control/" + payload.requestId, task(taskId) + "/control", payload);
|
|
102
|
+
},
|
|
103
|
+
updateTask: function (taskId, patch, requestId) {
|
|
104
|
+
return submitMutation(taskId + "/metadata", task(taskId) + "/metadata", { patch, requestId });
|
|
105
|
+
},
|
|
106
|
+
answerInput: function (taskId, inputId, answer) {
|
|
107
|
+
return submitMutation(taskId + "/input/" + inputId,
|
|
108
|
+
task(taskId) + "/inputs/" + encodeURIComponent(inputId) + "/answer", answer);
|
|
109
|
+
},
|
|
110
|
+
globalState: function (role) { return requestJson("/api/roles/" + encodeURIComponent(role) + "/control"); },
|
|
111
|
+
globalControl: function (role, input) {
|
|
112
|
+
return submitMutation("global/" + role, "/api/roles/" + encodeURIComponent(role) + "/control", input);
|
|
113
|
+
}
|
|
114
|
+
};
|
|
115
|
+
`;
|