sentinel-agentos 0.3.6 → 0.3.8
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/src/dashboard.html +175 -0
- package/package.json +3 -2
- package/LICENSE +0 -21
- package/README.md +0 -1797
- package/dist/adapters/evaluation-bridge.d.ts +0 -78
- package/dist/adapters/evaluation-bridge.d.ts.map +0 -1
- package/dist/adapters/evaluation-bridge.js +0 -273
- package/dist/adapters/evaluation-bridge.js.map +0 -1
- package/dist/adapters/memory-bridge.d.ts +0 -110
- package/dist/adapters/memory-bridge.d.ts.map +0 -1
- package/dist/adapters/memory-bridge.js +0 -316
- package/dist/adapters/memory-bridge.js.map +0 -1
- package/dist/adapters/migrate.d.ts +0 -2
- package/dist/adapters/migrate.d.ts.map +0 -1
- package/dist/adapters/migrate.js +0 -63
- package/dist/adapters/migrate.js.map +0 -1
- package/dist/api.d.ts +0 -151
- package/dist/api.d.ts.map +0 -1
- package/dist/api.js +0 -179
- package/dist/api.js.map +0 -1
- package/dist/cli.d.ts +0 -16
- package/dist/cli.d.ts.map +0 -1
- package/dist/cli.js +0 -350
- package/dist/cli.js.map +0 -1
- package/dist/core.d.ts +0 -151
- package/dist/core.d.ts.map +0 -1
- package/dist/core.js +0 -341
- package/dist/core.js.map +0 -1
- package/dist/evaluator/exec-evaluator.d.ts +0 -102
- package/dist/evaluator/exec-evaluator.d.ts.map +0 -1
- package/dist/evaluator/exec-evaluator.js +0 -266
- package/dist/evaluator/exec-evaluator.js.map +0 -1
- package/dist/evaluator/feedback.d.ts +0 -57
- package/dist/evaluator/feedback.d.ts.map +0 -1
- package/dist/evaluator/feedback.js +0 -225
- package/dist/evaluator/feedback.js.map +0 -1
- package/dist/evaluator/profiler.d.ts +0 -55
- package/dist/evaluator/profiler.d.ts.map +0 -1
- package/dist/evaluator/profiler.js +0 -117
- package/dist/evaluator/profiler.js.map +0 -1
- package/dist/guard/audit-log.d.ts +0 -47
- package/dist/guard/audit-log.d.ts.map +0 -1
- package/dist/guard/audit-log.js +0 -199
- package/dist/guard/audit-log.js.map +0 -1
- package/dist/guard/container-sandbox.d.ts +0 -25
- package/dist/guard/container-sandbox.d.ts.map +0 -1
- package/dist/guard/container-sandbox.js +0 -145
- package/dist/guard/container-sandbox.js.map +0 -1
- package/dist/guard/risk-gate.d.ts +0 -101
- package/dist/guard/risk-gate.d.ts.map +0 -1
- package/dist/guard/risk-gate.js +0 -200
- package/dist/guard/risk-gate.js.map +0 -1
- package/dist/guard/sandbox.d.ts +0 -112
- package/dist/guard/sandbox.d.ts.map +0 -1
- package/dist/guard/sandbox.js +0 -379
- package/dist/guard/sandbox.js.map +0 -1
- package/dist/guard/schema-gate.d.ts +0 -90
- package/dist/guard/schema-gate.d.ts.map +0 -1
- package/dist/guard/schema-gate.js +0 -452
- package/dist/guard/schema-gate.js.map +0 -1
- package/dist/guard/snapshot-verify.d.ts +0 -111
- package/dist/guard/snapshot-verify.d.ts.map +0 -1
- package/dist/guard/snapshot-verify.js +0 -571
- package/dist/guard/snapshot-verify.js.map +0 -1
- package/dist/index.d.ts +0 -28
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js +0 -59
- package/dist/index.js.map +0 -1
- package/dist/memory/episodic.d.ts +0 -76
- package/dist/memory/episodic.d.ts.map +0 -1
- package/dist/memory/episodic.js +0 -289
- package/dist/memory/episodic.js.map +0 -1
- package/dist/memory/semantic.d.ts +0 -68
- package/dist/memory/semantic.d.ts.map +0 -1
- package/dist/memory/semantic.js +0 -299
- package/dist/memory/semantic.js.map +0 -1
- package/dist/memory/working.d.ts +0 -53
- package/dist/memory/working.d.ts.map +0 -1
- package/dist/memory/working.js +0 -166
- package/dist/memory/working.js.map +0 -1
- package/dist/middleware/openclaw.d.ts +0 -45
- package/dist/middleware/openclaw.d.ts.map +0 -1
- package/dist/middleware/openclaw.js +0 -95
- package/dist/middleware/openclaw.js.map +0 -1
- package/dist/middleware/wrapper.d.ts +0 -54
- package/dist/middleware/wrapper.d.ts.map +0 -1
- package/dist/middleware/wrapper.js +0 -155
- package/dist/middleware/wrapper.js.map +0 -1
- package/dist/server.d.ts +0 -45
- package/dist/server.d.ts.map +0 -1
- package/dist/server.js +0 -246
- package/dist/server.js.map +0 -1
- package/dist/types/index.d.ts +0 -228
- package/dist/types/index.d.ts.map +0 -1
- package/dist/types/index.js +0 -23
- package/dist/types/index.js.map +0 -1
- package/scripts/sentinel-light.js +0 -234
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="zh-CN">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8">
|
|
5
|
+
<meta name="viewport" content="width=device-width,initial-scale=1.0">
|
|
6
|
+
<title>Sentinel AgentOS</title>
|
|
7
|
+
<style>
|
|
8
|
+
:root{--bg:#060912;--card:#0c111f;--border:#182035;--text:#e2e7f2;--dim:#4e5c79;--blue:#3b82f6;--green:#10b981;--red:#ef4444;--amber:#f59e0b}
|
|
9
|
+
*{margin:0;padding:0;box-sizing:border-box}
|
|
10
|
+
html,body{height:100%;overflow:hidden}
|
|
11
|
+
body{font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',sans-serif;background:var(--bg);color:var(--text);font-size:17px;display:flex}
|
|
12
|
+
|
|
13
|
+
.sb{width:260px;flex-shrink:0;background:var(--card);border-right:1px solid var(--border);display:flex;flex-direction:column;padding:22px;gap:20px;overflow-y:auto}
|
|
14
|
+
.sb-logo{display:flex;align-items:center;gap:10px;font-size:17px;font-weight:700}
|
|
15
|
+
.sb-logo i{width:30px;height:30px;border-radius:6px;background:linear-gradient(135deg,#3b82f6,#6366f1);display:grid;place-items:center;font-size:14px;font-style:normal}
|
|
16
|
+
.sb-logo em{font-weight:400;color:var(--dim);font-size:12px;font-style:normal}
|
|
17
|
+
.sb-sect h3{font-size:10px;font-weight:700;text-transform:uppercase;letter-spacing:1px;color:var(--dim);margin-bottom:8px}
|
|
18
|
+
.sb-stat{display:flex;justify-content:space-between;align-items:baseline;padding:8px 0;border-bottom:1px solid rgba(24,32,53,.5)}
|
|
19
|
+
.sb-stat .k{font-size:14px;color:var(--dim)}
|
|
20
|
+
.sb-stat .v{font-size:24px;font-weight:700;letter-spacing:-.4px}
|
|
21
|
+
|
|
22
|
+
.bar-wrap{display:flex;align-items:center;gap:12px;padding:8px 0}
|
|
23
|
+
.bar-track{flex:1;height:10px;border-radius:5px;background:rgba(24,32,53,.6);overflow:hidden;display:flex}
|
|
24
|
+
.bar-track .pass{background:var(--green);border-radius:5px 0 0 5px}
|
|
25
|
+
.bar-track .fail{background:var(--red);border-radius:0 5px 5px 0}
|
|
26
|
+
.bar-wrap .pct{font-size:18px;font-weight:700;letter-spacing:-.3px;min-width:46px;text-align:right}
|
|
27
|
+
.bar-wrap+.sub{font-size:11px;color:var(--dim)}
|
|
28
|
+
|
|
29
|
+
.g{color:var(--green)}.r{color:var(--red)}.a{color:var(--amber)}.p{color:#8b5cf6}
|
|
30
|
+
|
|
31
|
+
.main{flex:1;display:flex;flex-direction:column;overflow:hidden;min-width:0}
|
|
32
|
+
.topline{flex-shrink:0;display:flex;align-items:center;justify-content:space-between;padding:14px 28px;border-bottom:1px solid var(--border)}
|
|
33
|
+
.topline h2{font-size:14px;font-weight:700;text-transform:uppercase;letter-spacing:.8px;color:var(--dim)}
|
|
34
|
+
.topline .r{display:flex;align-items:center;gap:14px;font-size:13px;color:var(--dim)}
|
|
35
|
+
.topline .r b{width:7px;height:7px;border-radius:50%;display:inline-block;background:var(--green);animation:p 2s infinite}
|
|
36
|
+
@keyframes p{50%{opacity:.2}}
|
|
37
|
+
|
|
38
|
+
.tbl-wrap{flex:1;overflow-y:auto;padding:0 28px}
|
|
39
|
+
.tbl-wrap::-webkit-scrollbar{width:5px}
|
|
40
|
+
.tbl-wrap::-webkit-scrollbar-track{background:transparent}
|
|
41
|
+
.tbl-wrap::-webkit-scrollbar-thumb{background:var(--border);border-radius:2px}
|
|
42
|
+
|
|
43
|
+
table{width:100%;border-collapse:collapse;table-layout:fixed}
|
|
44
|
+
thead{position:sticky;top:0;z-index:2}
|
|
45
|
+
th{padding:13px 16px;text-align:left;font-size:11px;font-weight:700;text-transform:uppercase;letter-spacing:.6px;color:var(--dim);background:var(--bg);border-bottom:2px solid var(--border)}
|
|
46
|
+
th:first-child{width:46px;text-align:center;padding:13px 0}
|
|
47
|
+
th:nth-child(2){width:86px}
|
|
48
|
+
th:nth-child(4){width:100px}
|
|
49
|
+
th:nth-child(5){width:90px}
|
|
50
|
+
th:nth-child(6){width:90px}
|
|
51
|
+
|
|
52
|
+
td{padding:13px 16px;border-bottom:1px solid rgba(24,32,53,.35);font-size:16px;white-space:nowrap}
|
|
53
|
+
td:first-child{text-align:center;padding:13px 0;font-size:17px}
|
|
54
|
+
tr:hover{background:rgba(59,130,246,.02)}
|
|
55
|
+
tr.fail{background:rgba(239,68,68,.005)}tr.fail:hover{background:rgba(239,68,68,.015)}
|
|
56
|
+
|
|
57
|
+
.tag{display:inline-block;font-family:'SF Mono',monospace;font-size:13px;font-weight:600;padding:3px 9px;border-radius:4px}
|
|
58
|
+
.tag.e{color:#60a5fa;background:rgba(59,130,246,.06)}
|
|
59
|
+
.tag.w{color:#a78bfa;background:rgba(139,92,246,.06)}
|
|
60
|
+
.tag.d{color:#22d3ee;background:rgba(6,182,212,.06)}
|
|
61
|
+
.tag.g{color:#34d399;background:rgba(16,185,129,.06)}
|
|
62
|
+
tr.fail .tag.e,tr.fail .tag.w,tr.fail .tag.d,tr.fail .tag.g{color:#f87171;background:rgba(239,68,68,.06)}
|
|
63
|
+
|
|
64
|
+
.pm{font-family:'SF Mono',monospace;font-size:14px;color:var(--dim);display:block;overflow:hidden;text-overflow:ellipsis;opacity:.85}
|
|
65
|
+
.tm{font-family:'SF Mono',monospace;font-size:13px;color:var(--dim)}
|
|
66
|
+
|
|
67
|
+
.pill{display:inline-flex;align-items:center;gap:3px;font-size:12px;font-weight:600;padding:4px 10px;border-radius:10px}
|
|
68
|
+
.pill.ok{color:var(--green);background:rgba(16,185,129,.05)}
|
|
69
|
+
.pill.ko{color:var(--red);background:rgba(239,68,68,.05)}
|
|
70
|
+
|
|
71
|
+
.rw{display:flex;align-items:center;gap:8px}
|
|
72
|
+
.rw .bar{width:44px;height:3px;border-radius:2px;background:var(--border);overflow:hidden}
|
|
73
|
+
.rw .fll{height:100%;border-radius:2px}
|
|
74
|
+
.rw .n{font-family:'SF Mono',monospace;font-size:13px;font-weight:500}
|
|
75
|
+
|
|
76
|
+
.pgr{flex-shrink:0;padding:14px 28px;border-top:1px solid var(--border);display:flex;align-items:center;gap:8px;font-size:14px}
|
|
77
|
+
.pgr .btn{display:inline-flex;align-items:center;justify-content:center;width:34px;height:30px;background:var(--card);border:1px solid var(--border);color:var(--text);border-radius:5px;cursor:pointer;font-size:13px;transition:all .1s}
|
|
78
|
+
.pgr .btn:hover:not(:disabled){border-color:var(--blue);color:var(--blue)}
|
|
79
|
+
.pgr .btn:disabled{opacity:.08;cursor:default}
|
|
80
|
+
.pgr .pn{display:inline-flex;align-items:center;justify-content:center;width:30px;height:30px;border-radius:5px;font-size:13px;font-weight:600;cursor:pointer;color:var(--dim);border:1px solid transparent}
|
|
81
|
+
.pgr .pn:hover{border-color:var(--border);color:var(--text)}
|
|
82
|
+
.pgr .pn.on{background:var(--blue);color:#fff;border-color:var(--blue)}
|
|
83
|
+
|
|
84
|
+
.emp{text-align:center;padding:50px;color:var(--dim);font-size:16px}
|
|
85
|
+
</style>
|
|
86
|
+
</head>
|
|
87
|
+
<body>
|
|
88
|
+
|
|
89
|
+
<div class="sb">
|
|
90
|
+
<div class="sb-logo"><i>🛡️</i>Sentinel AgentOS<em> v0.3.7</em></div>
|
|
91
|
+
<div class="sb-sect"><h3>概览</h3>
|
|
92
|
+
<div class="sb-stat"><span class="k">总操作</span><span class="v" id="t1">—</span></div>
|
|
93
|
+
<div class="sb-stat"><span class="k">通过率</span><span class="v g" id="t2">—</span></div>
|
|
94
|
+
<div class="sb-stat"><span class="k">高风险</span><span class="v a" id="t3">—</span></div>
|
|
95
|
+
<div class="sb-stat"><span class="k">质量分</span><span class="v p" id="t4">—</span></div>
|
|
96
|
+
<div class="sb-stat"><span class="k">会话</span><span class="v g" id="t5">—</span></div>
|
|
97
|
+
</div>
|
|
98
|
+
<div class="sb-sect"><h3>审计通过率</h3>
|
|
99
|
+
<div class="bar-wrap"><div class="bar-track"><div class="pass" id="bp" style="width:100%"></div><div class="fail" id="bf" style="width:0%"></div></div><span class="pct g" id="c1">—</span></div>
|
|
100
|
+
<div class="sub" id="c1s">—</div></div>
|
|
101
|
+
<div class="sb-sect"><h3>质量评分</h3>
|
|
102
|
+
<div class="v p" style="font-size:38px;font-weight:700;letter-spacing:-.8px" id="c2">—</div>
|
|
103
|
+
<div style="font-size:11px;color:var(--dim)" id="c2s">Agent Profile</div>
|
|
104
|
+
</div>
|
|
105
|
+
<div style="font-size:11px;color:var(--dim);text-align:center;margin-top:auto" id="rt">—</div>
|
|
106
|
+
</div>
|
|
107
|
+
|
|
108
|
+
<div class="main">
|
|
109
|
+
<div class="topline">
|
|
110
|
+
<h2>审计记录</h2>
|
|
111
|
+
<div class="r"><b></b><span id="st">—</span> · <span id="up">—</span> · <span id="rc">—</span></div>
|
|
112
|
+
</div>
|
|
113
|
+
|
|
114
|
+
<div class="tbl-wrap">
|
|
115
|
+
<table>
|
|
116
|
+
<thead><tr><th>#</th><th>工具</th><th>参数</th><th>时间</th><th>状态</th><th>风险分</th></tr></thead>
|
|
117
|
+
<tbody id="tb"><tr><td colspan="6"><div class="emp">加载中…</div></td></tr></tbody>
|
|
118
|
+
</table>
|
|
119
|
+
</div>
|
|
120
|
+
|
|
121
|
+
<div class="pgr" id="pg"></div>
|
|
122
|
+
</div>
|
|
123
|
+
|
|
124
|
+
<script>
|
|
125
|
+
let items=[],P=20,cur=0;
|
|
126
|
+
|
|
127
|
+
async function R(){
|
|
128
|
+
try{
|
|
129
|
+
const d=await(await fetch('/pipeline/report')).json();
|
|
130
|
+
document.getElementById('st').textContent='已连接';document.querySelector('.r b').style.background='var(--green)';
|
|
131
|
+
const t=d.audit?.totalOperations||0,f=d.audit?.verifyFailures||0,p=t-f,r=t?Math.round(p/t*100):100,q=d.quality?.overallScore||50;
|
|
132
|
+
document.getElementById('t1').textContent=t;
|
|
133
|
+
document.getElementById('t2').textContent=r+'%';document.getElementById('t2').className='v '+(r>=90?'g':r>=70?'a':'r');
|
|
134
|
+
document.getElementById('t3').textContent=d.audit?.highRiskOps||0;
|
|
135
|
+
document.getElementById('t4').textContent=q;
|
|
136
|
+
document.getElementById('t5').textContent=d.audit?.sessionsTracked||1;
|
|
137
|
+
document.getElementById('up').textContent='运行 '+(d.uptime||'—');
|
|
138
|
+
document.getElementById('rt').textContent='刷新 '+new Date().toLocaleTimeString();
|
|
139
|
+
document.getElementById('c1').textContent=r+'%';
|
|
140
|
+
document.getElementById('c1s').textContent=p+' 通过 · '+f+' 失败';
|
|
141
|
+
document.getElementById('c2').textContent=q+'分';
|
|
142
|
+
document.getElementById('bp').style.width=r+'%';document.getElementById('bf').style.width=(100-r)+'%';
|
|
143
|
+
|
|
144
|
+
items=d.timeline||[];document.getElementById('rc').textContent='共 '+items.length+' 条';G(0);
|
|
145
|
+
}catch{
|
|
146
|
+
document.getElementById('st').textContent='断开';document.querySelector('.r b').style.background='var(--red)';
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
function G(p){cur=p;
|
|
151
|
+
const pages=Math.ceil(items.length/P),start=p*P,rows=items.slice(start,start+P);
|
|
152
|
+
const b=document.getElementById('tb');
|
|
153
|
+
if(!rows.length){b.innerHTML='<tr><td colspan="6"><div class="emp">暂无记录</div></td></tr>';return;}
|
|
154
|
+
const icons={exec:'⚙️',write:'✏️',edit:'🔧',read:'📖'},cls={exec:'e',write:'w',edit:'d',read:'g'};
|
|
155
|
+
b.innerHTML=rows.map(e=>{
|
|
156
|
+
const t=e.tool||'—',ok=e.verify!=='FAIL',s=Number(e.score)||0,rp=Math.min(s*10,100);
|
|
157
|
+
const rc=s>3?'var(--red)':s>1?'var(--amber)':'var(--green)';
|
|
158
|
+
const ts=e.ts?.slice(11,19)||'—',pr=(e.params||'').slice(0,140)||'—';
|
|
159
|
+
return `<tr class="${ok?'':'fail'}">
|
|
160
|
+
<td>${icons[t]||'🔹'}</td><td><span class="tag ${cls[t]||''}">${t}</span></td>
|
|
161
|
+
<td><span class="pm" title="${pr}">${pr}</span></td><td><span class="tm">${ts}</span></td>
|
|
162
|
+
<td><span class="pill ${ok?'ok':'ko'}">${ok?'● 通过':'● 拦截'}</span></td>
|
|
163
|
+
<td><div class="rw"><div class="bar"><div class="fll" style="width:${rp}%;background:${rc}"></div></div><span class="n" style="color:${rc}">${s.toFixed(1)}</span></div></td>
|
|
164
|
+
</tr>`;
|
|
165
|
+
}).join('');
|
|
166
|
+
|
|
167
|
+
const pg=document.getElementById('pg');if(pages<=1){pg.innerHTML='';return;}
|
|
168
|
+
let ns='';for(let i=0;i<pages;i++){const g=i===0||i===pages-1||Math.abs(i-p)<=1;if(g)ns+=`<span class="pn${i===p?' on':''}" onclick="G(${i})">${i+1}</span>`;else if((i===1&&p>2)||(i===pages-2&&p<pages-3))ns+='<span style="color:var(--dim);padding:0 2px">…</span>';}
|
|
169
|
+
pg.innerHTML=`<span class="btn" onclick="G(${p-1})" ${p===0?'disabled':''}>◀</span>${ns}<span class="btn" onclick="G(${p+1})" ${p>=pages-1?'disabled':''}>▶</span>`;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
R();setInterval(R,5000);
|
|
173
|
+
</script>
|
|
174
|
+
</body>
|
|
175
|
+
</html>
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "sentinel-agentos",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.8",
|
|
4
4
|
"description": "Sentinel AgentOS — 确定性 Guard 层 + 分层记忆 + 自动评估,让任何 Agent 变得可靠、可审计、可改进",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"agent",
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
"LICENSE"
|
|
31
31
|
],
|
|
32
32
|
"scripts": {
|
|
33
|
-
"build": "tsc",
|
|
33
|
+
"build": "tsc && npx copyfiles src/dashboard.html dist/",
|
|
34
34
|
"dev": "tsc --watch",
|
|
35
35
|
"test": "jest",
|
|
36
36
|
"test:watch": "jest --watch",
|
|
@@ -48,6 +48,7 @@
|
|
|
48
48
|
"@types/node": "^20.0.0",
|
|
49
49
|
"@typescript-eslint/eslint-plugin": "^7.0.0",
|
|
50
50
|
"@typescript-eslint/parser": "^7.0.0",
|
|
51
|
+
"copyfiles": "^2.4.1",
|
|
51
52
|
"eslint": "^8.0.0",
|
|
52
53
|
"eslint-config-prettier": "^9.0.0",
|
|
53
54
|
"fluent-ffmpeg": "^2.1.3",
|
package/LICENSE
DELETED
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
MIT License
|
|
2
|
-
|
|
3
|
-
Copyright (c) 2026 jishuanjimingtian
|
|
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.
|