maqam 0.1.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/LICENSE +21 -0
- package/README.md +176 -0
- package/app/app.js +113 -0
- package/app/assets/maqam-brand-board.png +0 -0
- package/app/assets/maqam-logo.svg +17 -0
- package/app/assets/maqam-readme-hero.png +0 -0
- package/app/assets/maqam-system-map.svg +114 -0
- package/app/index.html +113 -0
- package/app/styles.css +397 -0
- package/bin/ajnas-crawl.js +119 -0
- package/bin/maqam.js +22 -0
- package/package.json +74 -0
- package/src/framework/errors.js +35 -0
- package/src/framework/evidence-ledger.js +72 -0
- package/src/framework/policy.js +119 -0
- package/src/framework/research-workflow.js +80 -0
- package/src/framework/runtime.js +101 -0
- package/src/framework/skill-registry.js +52 -0
- package/src/framework/tool-gateway.js +65 -0
- package/src/index.js +351 -0
- package/src/maqam/server.js +189 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Ajnas
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
# Maqam
|
|
2
|
+
|
|
3
|
+

|
|
4
|
+
|
|
5
|
+
Maqam is an MIT-licensed Ajnas agent framework for governed workflows. It combines a local agent runtime, policy engine, evidence ledger, skill registry, tool gateway, human-review-ready approval errors, and a crawler-backed research workflow.
|
|
6
|
+
|
|
7
|
+
The crawler is no longer the product center; it is the first governed connector. Maqam is meant for enterprise agent workflows that need inspectable runs, source-backed outputs, compliance-friendly defaults, and no required hosted service.
|
|
8
|
+
|
|
9
|
+

|
|
10
|
+
|
|
11
|
+
## What Ships
|
|
12
|
+
|
|
13
|
+
- `AgentRuntime`: sequential workflow execution with retries, trace events, task outputs, and policy preflight.
|
|
14
|
+
- `PolicyEngine`: deterministic goal and tool-call decisions for allowed tools, origins, limits, and approval gates.
|
|
15
|
+
- `EvidenceLedger`: provenance records, claim links, source hashes, confidence, and unsupported-claim checks.
|
|
16
|
+
- `ToolGateway`: one governed path for external tool execution.
|
|
17
|
+
- `SkillRegistry`: lightweight skill metadata registration and selection.
|
|
18
|
+
- `createResearchWorkflow`: crawler-backed source collection, synthesis, and quality checks.
|
|
19
|
+
- `maqam`: local web console for running governed research workflows.
|
|
20
|
+
- `maqam-crawl`: respectful crawler CLI that obeys `robots.txt` by default.
|
|
21
|
+
|
|
22
|
+
## Why It Matters
|
|
23
|
+
|
|
24
|
+
Agent systems fail in production when tools run outside policy, outputs cannot be traced to sources, and risky actions happen without approval. Maqam makes those control points explicit:
|
|
25
|
+
|
|
26
|
+
- Every workflow starts with policy preflight.
|
|
27
|
+
- Every tool call goes through `ToolGateway`.
|
|
28
|
+
- Every source-backed claim can be recorded in `EvidenceLedger`.
|
|
29
|
+
- Every run returns trace data for inspection and replay.
|
|
30
|
+
- Approval-required actions fail closed with `ApprovalRequiredError`.
|
|
31
|
+
- The crawler supports research and ingestion while preserving compliance defaults.
|
|
32
|
+
|
|
33
|
+
## Install
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
npm install -g maqam
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
Run the local console:
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
maqam
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
Then open `http://127.0.0.1:8787`.
|
|
46
|
+
|
|
47
|
+
Run without global install:
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
npx maqam --port 8787
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
## Crawler CLI
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
maqam-crawl https://example.com --max-pages 50 --jsonl --output crawl.jsonl
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
Legacy aliases `ajnas-crawl` and `ajnas-agent-crawler` are kept for compatibility.
|
|
60
|
+
|
|
61
|
+
Options:
|
|
62
|
+
|
|
63
|
+
- `--max-pages <n>`: maximum pages to return. Default: `50`
|
|
64
|
+
- `--concurrency <n>`: concurrent workers. Default: `4`
|
|
65
|
+
- `--delay <ms>`: minimum delay per origin. Default: `250`
|
|
66
|
+
- `--timeout <ms>`: request timeout. Default: `15000`
|
|
67
|
+
- `--sitemaps`: discover URLs from robots.txt sitemaps and `/sitemap.xml`
|
|
68
|
+
- `--all-origins`: allow crawling across discovered origins
|
|
69
|
+
- `--jsonl`: output JSON Lines instead of a JSON array
|
|
70
|
+
- `--output <file>`: write output to a file
|
|
71
|
+
- `--user-agent <ua>`: custom user agent
|
|
72
|
+
|
|
73
|
+
## Framework SDK
|
|
74
|
+
|
|
75
|
+
```js
|
|
76
|
+
import {
|
|
77
|
+
AgentRuntime,
|
|
78
|
+
EvidenceLedger,
|
|
79
|
+
PolicyEngine,
|
|
80
|
+
ToolGateway,
|
|
81
|
+
createCrawlerTool,
|
|
82
|
+
createResearchWorkflow
|
|
83
|
+
} from "maqam";
|
|
84
|
+
|
|
85
|
+
const evidenceLedger = new EvidenceLedger();
|
|
86
|
+
const policyEngine = new PolicyEngine({
|
|
87
|
+
allowedTools: ["crawler"],
|
|
88
|
+
allowedOrigins: ["https://github.com", "https://www.npmjs.com"]
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
const gateway = new ToolGateway({ policyEngine, evidenceLedger });
|
|
92
|
+
gateway.registerTool("crawler", createCrawlerTool());
|
|
93
|
+
|
|
94
|
+
const runtime = new AgentRuntime({ policyEngine, evidenceLedger, toolGateway: gateway });
|
|
95
|
+
const result = await runtime.runWorkflow(
|
|
96
|
+
createResearchWorkflow({
|
|
97
|
+
seeds: ["https://github.com/apify/crawlee"],
|
|
98
|
+
maxPages: 5
|
|
99
|
+
}),
|
|
100
|
+
{
|
|
101
|
+
objective: "Research permissive OSS agent framework projects",
|
|
102
|
+
allowedTools: ["crawler"],
|
|
103
|
+
allowedOrigins: ["https://github.com"]
|
|
104
|
+
}
|
|
105
|
+
);
|
|
106
|
+
|
|
107
|
+
console.log(result.outputs.synthesize_report.candidates);
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
## Crawler API
|
|
111
|
+
|
|
112
|
+
```js
|
|
113
|
+
import { crawl } from "maqam";
|
|
114
|
+
|
|
115
|
+
const pages = await crawl({
|
|
116
|
+
seeds: ["https://example.com"],
|
|
117
|
+
maxPages: 25,
|
|
118
|
+
concurrency: 4,
|
|
119
|
+
includeSitemaps: true,
|
|
120
|
+
onPage(page) {
|
|
121
|
+
console.log(page.url, page.title);
|
|
122
|
+
}
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
console.log(pages[0].markdown);
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
## Maqam Console
|
|
129
|
+
|
|
130
|
+
```bash
|
|
131
|
+
npm run maqam
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
The console runs a governed research workflow through:
|
|
135
|
+
|
|
136
|
+
- `PolicyEngine`: allows or denies goals and tool calls.
|
|
137
|
+
- `ToolGateway`: routes all external work through policy checks.
|
|
138
|
+
- `EvidenceLedger`: records source-backed evidence and claim support.
|
|
139
|
+
- `AgentRuntime`: executes workflow tasks with traces and retries.
|
|
140
|
+
- `createResearchWorkflow`: composes crawler collection, synthesis, and quality checks.
|
|
141
|
+
|
|
142
|
+
Brand assets live in `app/assets/`, including `maqam-logo.svg` and `maqam-brand-board.png`.
|
|
143
|
+
|
|
144
|
+
## Principles
|
|
145
|
+
|
|
146
|
+
- Respect `robots.txt` by default.
|
|
147
|
+
- Use a clear user agent.
|
|
148
|
+
- Rate-limit per origin.
|
|
149
|
+
- Avoid bypassing access controls, paywalls, anti-bot systems, or private content.
|
|
150
|
+
- No required AI provider dependency.
|
|
151
|
+
- No required external hosted service.
|
|
152
|
+
- Produce JSON/JSONL output that agents can consume directly.
|
|
153
|
+
|
|
154
|
+
## What This Is Not
|
|
155
|
+
|
|
156
|
+
Maqam is not a stealth scraper and does not include bypass tooling. It will not help evade login walls, paywalls, anti-bot protections, CAPTCHA, robots.txt, or authorization boundaries.
|
|
157
|
+
|
|
158
|
+
## Development
|
|
159
|
+
|
|
160
|
+
```bash
|
|
161
|
+
npm install
|
|
162
|
+
npm test
|
|
163
|
+
npm pack --dry-run
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
## Publish
|
|
167
|
+
|
|
168
|
+
```bash
|
|
169
|
+
npm publish --access public
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
Publishing requires an authenticated npm session with permission to publish the `maqam` package.
|
|
173
|
+
|
|
174
|
+
## License
|
|
175
|
+
|
|
176
|
+
MIT
|
package/app/app.js
ADDED
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
const form = document.querySelector("#research-form");
|
|
2
|
+
const statusEl = document.querySelector("#run-status");
|
|
3
|
+
const candidatesEl = document.querySelector("#candidates");
|
|
4
|
+
const evidenceEl = document.querySelector("#evidence-list");
|
|
5
|
+
const traceEl = document.querySelector("#trace-list");
|
|
6
|
+
const metricRuntime = document.querySelector("#metric-runtime");
|
|
7
|
+
const metricEvidence = document.querySelector("#metric-evidence");
|
|
8
|
+
const metricClaims = document.querySelector("#metric-claims");
|
|
9
|
+
const metricTools = document.querySelector("#metric-tools");
|
|
10
|
+
|
|
11
|
+
function setStatus(text, kind = "ready") {
|
|
12
|
+
statusEl.textContent = text;
|
|
13
|
+
statusEl.className = kind === "error" ? "error" : "";
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
function truncate(text, length = 180) {
|
|
17
|
+
if (!text) return "";
|
|
18
|
+
return text.length > length ? `${text.slice(0, length - 1)}...` : text;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
function candidateTemplate(candidate) {
|
|
22
|
+
return `
|
|
23
|
+
<article>
|
|
24
|
+
<h3>${candidate.name || "Untitled candidate"}</h3>
|
|
25
|
+
<p>${truncate(candidate.whatItDoes || "No summary returned.")}</p>
|
|
26
|
+
<div class="tag-row">
|
|
27
|
+
<a class="tag" href="${candidate.url}" target="_blank" rel="noreferrer">Source</a>
|
|
28
|
+
<span class="tag">${candidate.recommendation || "review"}</span>
|
|
29
|
+
</div>
|
|
30
|
+
</article>
|
|
31
|
+
`;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
function evidenceTemplate(record) {
|
|
35
|
+
return `
|
|
36
|
+
<article>
|
|
37
|
+
<h3>${record.sourceType}: ${record.source}</h3>
|
|
38
|
+
<p>${truncate(record.excerpt || "No excerpt captured.", 220)}</p>
|
|
39
|
+
<div class="tag-row">
|
|
40
|
+
<span class="tag">${record.tool || "tool"}</span>
|
|
41
|
+
<span class="tag">${Math.round((record.confidence || 0) * 100)}% confidence</span>
|
|
42
|
+
</div>
|
|
43
|
+
</article>
|
|
44
|
+
`;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
function traceTemplate(item) {
|
|
48
|
+
return `<li>${item.taskId || item.toolName}: ${item.status || item.decision?.status || "completed"}</li>`;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
function renderRun(payload) {
|
|
52
|
+
const run = payload.run;
|
|
53
|
+
const candidates = run.outputs?.synthesize_report?.candidates || [];
|
|
54
|
+
const evidence = run.evidence?.evidence || [];
|
|
55
|
+
const claims = run.evidence?.claims || [];
|
|
56
|
+
const toolTrace = payload.toolTrace || [];
|
|
57
|
+
|
|
58
|
+
candidatesEl.className = candidates.length ? "stack" : "stack empty";
|
|
59
|
+
candidatesEl.innerHTML = candidates.length
|
|
60
|
+
? candidates.map(candidateTemplate).join("")
|
|
61
|
+
: "No candidates returned.";
|
|
62
|
+
|
|
63
|
+
evidenceEl.className = evidence.length ? "stack" : "stack empty";
|
|
64
|
+
evidenceEl.innerHTML = evidence.length
|
|
65
|
+
? evidence.map(evidenceTemplate).join("")
|
|
66
|
+
: "No evidence records returned.";
|
|
67
|
+
|
|
68
|
+
traceEl.innerHTML = [
|
|
69
|
+
...(run.trace || []).map(traceTemplate),
|
|
70
|
+
...toolTrace.map(traceTemplate)
|
|
71
|
+
].join("");
|
|
72
|
+
|
|
73
|
+
metricRuntime.textContent = run.status;
|
|
74
|
+
metricEvidence.textContent = `${evidence.length} records`;
|
|
75
|
+
metricClaims.textContent = `${claims.length} checked`;
|
|
76
|
+
metricTools.textContent = `${toolTrace.length} calls`;
|
|
77
|
+
setStatus(run.status === "completed" ? "Completed" : run.status, run.status === "failed" ? "error" : "ready");
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
form.addEventListener("submit", async (event) => {
|
|
81
|
+
event.preventDefault();
|
|
82
|
+
const button = form.querySelector("button");
|
|
83
|
+
const data = new FormData(form);
|
|
84
|
+
const seed = data.get("seed");
|
|
85
|
+
const maxPages = Number(data.get("maxPages"));
|
|
86
|
+
const sameOrigin = data.get("sameOrigin") === "true";
|
|
87
|
+
|
|
88
|
+
button.disabled = true;
|
|
89
|
+
setStatus("Running");
|
|
90
|
+
metricRuntime.textContent = "Running";
|
|
91
|
+
candidatesEl.className = "stack empty";
|
|
92
|
+
candidatesEl.textContent = "Collecting sources through policy gateway...";
|
|
93
|
+
evidenceEl.className = "stack empty";
|
|
94
|
+
evidenceEl.textContent = "Waiting for evidence records...";
|
|
95
|
+
|
|
96
|
+
try {
|
|
97
|
+
const response = await fetch("/api/runs/research", {
|
|
98
|
+
method: "POST",
|
|
99
|
+
headers: { "content-type": "application/json" },
|
|
100
|
+
body: JSON.stringify({ seeds: [seed], maxPages, sameOrigin })
|
|
101
|
+
});
|
|
102
|
+
const payload = await response.json();
|
|
103
|
+
if (!response.ok) throw new Error(payload.error || "Run failed");
|
|
104
|
+
renderRun(payload);
|
|
105
|
+
} catch (error) {
|
|
106
|
+
setStatus("Error", "error");
|
|
107
|
+
candidatesEl.className = "stack empty error";
|
|
108
|
+
candidatesEl.textContent = error.message || "Unable to run workflow.";
|
|
109
|
+
metricRuntime.textContent = "Error";
|
|
110
|
+
} finally {
|
|
111
|
+
button.disabled = false;
|
|
112
|
+
}
|
|
113
|
+
});
|
|
Binary file
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
<svg width="128" height="128" viewBox="0 0 128 128" fill="none" xmlns="http://www.w3.org/2000/svg" role="img" aria-labelledby="title desc">
|
|
2
|
+
<title id="title">Maqam logo</title>
|
|
3
|
+
<desc id="desc">A geometric M mark built from interlocking frames and a protected evidence core.</desc>
|
|
4
|
+
<rect width="128" height="128" rx="30" fill="#0C1110"/>
|
|
5
|
+
<path d="M27 91V37h17l20 28 20-28h17v54H84V62L66 88h-4L44 62v29H27Z" fill="#F4F7F3"/>
|
|
6
|
+
<path d="M44 37h20l-8 12H44V37Z" fill="#48C7FF"/>
|
|
7
|
+
<path d="M84 37h17v17H90l-6-17Z" fill="#84E07F"/>
|
|
8
|
+
<path d="M64 65 84 37h17L70 80h-12L27 37h17l20 28Z" fill="url(#g)" fill-opacity=".62"/>
|
|
9
|
+
<circle cx="64" cy="72" r="9" fill="#0C1110" stroke="#84E07F" stroke-width="4"/>
|
|
10
|
+
<path d="M35 100h58" stroke="#48C7FF" stroke-width="5" stroke-linecap="round"/>
|
|
11
|
+
<defs>
|
|
12
|
+
<linearGradient id="g" x1="27" y1="37" x2="101" y2="80" gradientUnits="userSpaceOnUse">
|
|
13
|
+
<stop stop-color="#48C7FF"/>
|
|
14
|
+
<stop offset="1" stop-color="#84E07F"/>
|
|
15
|
+
</linearGradient>
|
|
16
|
+
</defs>
|
|
17
|
+
</svg>
|
|
Binary file
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="1200" height="630" viewBox="0 0 1200 630" role="img" aria-labelledby="title desc">
|
|
2
|
+
<title id="title">Maqam system map</title>
|
|
3
|
+
<desc id="desc">A governed agent workflow from goal intake through policy, runtime, tools, evidence, approvals, and verified output.</desc>
|
|
4
|
+
<defs>
|
|
5
|
+
<linearGradient id="bg" x1="0" x2="1" y1="0" y2="1">
|
|
6
|
+
<stop offset="0" stop-color="#070A0D"/>
|
|
7
|
+
<stop offset="0.52" stop-color="#0B0D10"/>
|
|
8
|
+
<stop offset="1" stop-color="#111816"/>
|
|
9
|
+
</linearGradient>
|
|
10
|
+
<linearGradient id="blue" x1="0" x2="1">
|
|
11
|
+
<stop offset="0" stop-color="#1D4ED8"/>
|
|
12
|
+
<stop offset="1" stop-color="#3B82F6"/>
|
|
13
|
+
</linearGradient>
|
|
14
|
+
<linearGradient id="green" x1="0" x2="1">
|
|
15
|
+
<stop offset="0" stop-color="#16A34A"/>
|
|
16
|
+
<stop offset="1" stop-color="#22C55E"/>
|
|
17
|
+
</linearGradient>
|
|
18
|
+
<filter id="glow" x="-30%" y="-30%" width="160%" height="160%">
|
|
19
|
+
<feGaussianBlur stdDeviation="4" result="blur"/>
|
|
20
|
+
<feMerge>
|
|
21
|
+
<feMergeNode in="blur"/>
|
|
22
|
+
<feMergeNode in="SourceGraphic"/>
|
|
23
|
+
</feMerge>
|
|
24
|
+
</filter>
|
|
25
|
+
<style>
|
|
26
|
+
.label{font:700 20px Segoe UI,Arial,sans-serif;fill:#F5F6F8}
|
|
27
|
+
.small{font:500 14px Segoe UI,Arial,sans-serif;fill:#A9B7B0}
|
|
28
|
+
.tiny{font:600 12px Segoe UI,Arial,sans-serif;fill:#A9B7B0;letter-spacing:.08em}
|
|
29
|
+
.panel{fill:#111816;stroke:#2D3935;stroke-width:1.5}
|
|
30
|
+
.line{fill:none;stroke:#334155;stroke-width:2}
|
|
31
|
+
.blueLine{fill:none;stroke:#2563EB;stroke-width:3}
|
|
32
|
+
.greenLine{fill:none;stroke:#22C55E;stroke-width:3}
|
|
33
|
+
</style>
|
|
34
|
+
</defs>
|
|
35
|
+
<rect width="1200" height="630" rx="28" fill="url(#bg)"/>
|
|
36
|
+
<path d="M0 126H1200M0 252H1200M0 378H1200M0 504H1200M200 0V630M400 0V630M600 0V630M800 0V630M1000 0V630" stroke="#1F2937" stroke-width="1" opacity=".32"/>
|
|
37
|
+
|
|
38
|
+
<g transform="translate(54 46)">
|
|
39
|
+
<path d="M0 70V10L100 68V168H20V92L100 138" fill="none" stroke="url(#blue)" stroke-width="12" stroke-linejoin="round" filter="url(#glow)"/>
|
|
40
|
+
<path d="M204 70V10L104 68V168H184V92L104 138" fill="none" stroke="url(#green)" stroke-width="12" stroke-linejoin="round" filter="url(#glow)"/>
|
|
41
|
+
<rect x="92" y="102" width="20" height="20" fill="#F5F6F8" rx="2"/>
|
|
42
|
+
</g>
|
|
43
|
+
|
|
44
|
+
<text x="54" y="288" class="tiny" fill="#3B82F6">MAQAM</text>
|
|
45
|
+
<text x="54" y="328" class="label" font-size="44">Compose governed agents</text>
|
|
46
|
+
<text x="54" y="364" class="small">Small, trusted skills. One controlled workflow.</text>
|
|
47
|
+
|
|
48
|
+
<g transform="translate(360 70)">
|
|
49
|
+
<rect class="panel" width="232" height="86" rx="14"/>
|
|
50
|
+
<text x="24" y="36" class="label">PolicyEngine</text>
|
|
51
|
+
<text x="24" y="62" class="small">allow, deny, limit, approve</text>
|
|
52
|
+
</g>
|
|
53
|
+
<g transform="translate(360 210)">
|
|
54
|
+
<rect class="panel" width="232" height="86" rx="14"/>
|
|
55
|
+
<text x="24" y="36" class="label">AgentRuntime</text>
|
|
56
|
+
<text x="24" y="62" class="small">tasks, retries, traces</text>
|
|
57
|
+
</g>
|
|
58
|
+
<g transform="translate(360 350)">
|
|
59
|
+
<rect class="panel" width="232" height="86" rx="14"/>
|
|
60
|
+
<text x="24" y="36" class="label">SkillRegistry</text>
|
|
61
|
+
<text x="24" y="62" class="small">skills, triggers, scores</text>
|
|
62
|
+
</g>
|
|
63
|
+
|
|
64
|
+
<g transform="translate(704 70)">
|
|
65
|
+
<rect class="panel" width="232" height="86" rx="14"/>
|
|
66
|
+
<text x="24" y="36" class="label">ToolGateway</text>
|
|
67
|
+
<text x="24" y="62" class="small">crawler and connectors</text>
|
|
68
|
+
</g>
|
|
69
|
+
<g transform="translate(704 210)">
|
|
70
|
+
<rect class="panel" width="232" height="86" rx="14"/>
|
|
71
|
+
<text x="24" y="36" class="label">EvidenceLedger</text>
|
|
72
|
+
<text x="24" y="62" class="small">sources, claims, hashes</text>
|
|
73
|
+
</g>
|
|
74
|
+
<g transform="translate(704 350)">
|
|
75
|
+
<rect class="panel" width="232" height="86" rx="14"/>
|
|
76
|
+
<text x="24" y="36" class="label">Human Review</text>
|
|
77
|
+
<text x="24" y="62" class="small">approval-ready gates</text>
|
|
78
|
+
</g>
|
|
79
|
+
|
|
80
|
+
<g transform="translate(508 495)">
|
|
81
|
+
<rect width="320" height="72" rx="16" fill="#0B1220" stroke="#2563EB" stroke-width="1.5"/>
|
|
82
|
+
<text x="24" y="31" class="label">Verified Output</text>
|
|
83
|
+
<text x="24" y="54" class="small">auditable reports, JSON, and run traces</text>
|
|
84
|
+
</g>
|
|
85
|
+
|
|
86
|
+
<path class="blueLine" d="M592 113H704"/>
|
|
87
|
+
<path class="blueLine" d="M592 253H704"/>
|
|
88
|
+
<path class="greenLine" d="M592 393H704"/>
|
|
89
|
+
<path class="line" d="M476 156V210"/>
|
|
90
|
+
<path class="line" d="M476 296V350"/>
|
|
91
|
+
<path class="line" d="M820 156V210"/>
|
|
92
|
+
<path class="line" d="M820 296V350"/>
|
|
93
|
+
<path class="greenLine" d="M820 436V495"/>
|
|
94
|
+
<path class="blueLine" d="M476 436V531H508"/>
|
|
95
|
+
|
|
96
|
+
<circle cx="592" cy="113" r="7" fill="#2563EB"/>
|
|
97
|
+
<circle cx="704" cy="113" r="7" fill="#22C55E"/>
|
|
98
|
+
<circle cx="592" cy="253" r="7" fill="#2563EB"/>
|
|
99
|
+
<circle cx="704" cy="253" r="7" fill="#22C55E"/>
|
|
100
|
+
<circle cx="592" cy="393" r="7" fill="#2563EB"/>
|
|
101
|
+
<circle cx="704" cy="393" r="7" fill="#22C55E"/>
|
|
102
|
+
<circle cx="820" cy="495" r="7" fill="#22C55E"/>
|
|
103
|
+
|
|
104
|
+
<g transform="translate(990 112)">
|
|
105
|
+
<rect class="panel" width="142" height="320" rx="16"/>
|
|
106
|
+
<text x="22" y="42" class="tiny">POLICY CHIPS</text>
|
|
107
|
+
<text x="22" y="82" class="small">Access Control</text>
|
|
108
|
+
<text x="22" y="122" class="small">PII Protection</text>
|
|
109
|
+
<text x="22" y="162" class="small">Tool Allowlist</text>
|
|
110
|
+
<text x="22" y="202" class="small">Rate Limits</text>
|
|
111
|
+
<text x="22" y="262" class="tiny">STATE</text>
|
|
112
|
+
<text x="22" y="300" class="small" fill="#22C55E">Governed</text>
|
|
113
|
+
</g>
|
|
114
|
+
</svg>
|
package/app/index.html
ADDED
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="utf-8">
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
6
|
+
<meta name="description" content="Maqam is an enterprise agent framework console for governed research workflows.">
|
|
7
|
+
<title>Maqam | Compose governed agents</title>
|
|
8
|
+
<link rel="icon" href="/assets/maqam-logo.svg" type="image/svg+xml">
|
|
9
|
+
<link rel="stylesheet" href="/styles.css">
|
|
10
|
+
</head>
|
|
11
|
+
<body>
|
|
12
|
+
<div class="shell">
|
|
13
|
+
<header class="topbar">
|
|
14
|
+
<a class="brand" href="/" aria-label="Maqam home">
|
|
15
|
+
<img src="/assets/maqam-logo.svg" alt="" width="44" height="44">
|
|
16
|
+
<span>
|
|
17
|
+
<strong>Maqam</strong>
|
|
18
|
+
<small>Compose governed agents</small>
|
|
19
|
+
</span>
|
|
20
|
+
</a>
|
|
21
|
+
<nav class="nav" aria-label="Primary">
|
|
22
|
+
<a href="#run">Run</a>
|
|
23
|
+
<a href="#evidence">Evidence</a>
|
|
24
|
+
<a href="#policy">Policy</a>
|
|
25
|
+
</nav>
|
|
26
|
+
</header>
|
|
27
|
+
|
|
28
|
+
<main>
|
|
29
|
+
<section class="hero" aria-labelledby="hero-title">
|
|
30
|
+
<div class="hero-copy">
|
|
31
|
+
<p class="kicker">Enterprise agent framework</p>
|
|
32
|
+
<h1 id="hero-title">Build agent workflows that can be inspected, governed, and trusted.</h1>
|
|
33
|
+
<p class="lede">Maqam composes skills, tools, policy, evidence, and runtime traces into one controlled workflow surface.</p>
|
|
34
|
+
</div>
|
|
35
|
+
<div class="run-panel" id="run">
|
|
36
|
+
<div class="panel-header">
|
|
37
|
+
<span>Governed research run</span>
|
|
38
|
+
<strong id="run-status">Ready</strong>
|
|
39
|
+
</div>
|
|
40
|
+
<form id="research-form">
|
|
41
|
+
<label for="seed-url">Seed URL</label>
|
|
42
|
+
<input id="seed-url" name="seed" type="url" value="https://github.com/apify/crawlee" autocomplete="url" required>
|
|
43
|
+
<div class="form-grid">
|
|
44
|
+
<label>
|
|
45
|
+
Max pages
|
|
46
|
+
<input name="maxPages" type="number" min="1" max="25" value="2" autocomplete="off">
|
|
47
|
+
</label>
|
|
48
|
+
<label>
|
|
49
|
+
Same origin
|
|
50
|
+
<select name="sameOrigin">
|
|
51
|
+
<option value="true" selected>On</option>
|
|
52
|
+
<option value="false">Off</option>
|
|
53
|
+
</select>
|
|
54
|
+
</label>
|
|
55
|
+
</div>
|
|
56
|
+
<button type="submit">Run governed workflow</button>
|
|
57
|
+
<p class="hint">The server enforces policy before tool execution and records evidence for the synthesized result.</p>
|
|
58
|
+
</form>
|
|
59
|
+
</div>
|
|
60
|
+
</section>
|
|
61
|
+
|
|
62
|
+
<section class="metrics" aria-label="Run metrics">
|
|
63
|
+
<article>
|
|
64
|
+
<span>Runtime</span>
|
|
65
|
+
<strong id="metric-runtime">Idle</strong>
|
|
66
|
+
</article>
|
|
67
|
+
<article>
|
|
68
|
+
<span>Evidence</span>
|
|
69
|
+
<strong id="metric-evidence">0 records</strong>
|
|
70
|
+
</article>
|
|
71
|
+
<article>
|
|
72
|
+
<span>Claims</span>
|
|
73
|
+
<strong id="metric-claims">0 checked</strong>
|
|
74
|
+
</article>
|
|
75
|
+
<article>
|
|
76
|
+
<span>Gateway</span>
|
|
77
|
+
<strong id="metric-tools">0 calls</strong>
|
|
78
|
+
</article>
|
|
79
|
+
</section>
|
|
80
|
+
|
|
81
|
+
<section class="workspace">
|
|
82
|
+
<div class="column">
|
|
83
|
+
<div class="section-heading">
|
|
84
|
+
<h2>Candidates</h2>
|
|
85
|
+
<p>What the workflow produced from governed source collection.</p>
|
|
86
|
+
</div>
|
|
87
|
+
<div id="candidates" class="stack empty">Run a workflow to inspect candidates.</div>
|
|
88
|
+
</div>
|
|
89
|
+
<div class="column">
|
|
90
|
+
<div class="section-heading" id="evidence">
|
|
91
|
+
<h2>Evidence ledger</h2>
|
|
92
|
+
<p>Source-backed records linked to claims.</p>
|
|
93
|
+
</div>
|
|
94
|
+
<div id="evidence-list" class="stack empty">Evidence records will appear here.</div>
|
|
95
|
+
</div>
|
|
96
|
+
</section>
|
|
97
|
+
|
|
98
|
+
<section class="policy-band" id="policy">
|
|
99
|
+
<div>
|
|
100
|
+
<h2>Policy path</h2>
|
|
101
|
+
<p>Goal preflight, tool authorization, evidence capture, synthesis, and quality checks are first-class run steps.</p>
|
|
102
|
+
</div>
|
|
103
|
+
<ol id="trace-list">
|
|
104
|
+
<li>Preflight waiting</li>
|
|
105
|
+
<li>Tool gateway waiting</li>
|
|
106
|
+
<li>Evidence ledger waiting</li>
|
|
107
|
+
</ol>
|
|
108
|
+
</section>
|
|
109
|
+
</main>
|
|
110
|
+
</div>
|
|
111
|
+
<script type="module" src="/app.js"></script>
|
|
112
|
+
</body>
|
|
113
|
+
</html>
|