@datalayer/agent-runtimes 1.5.41 → 1.5.42
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-embed/datalayer-app-main.js +1 -1
- package/lib/examples/ShieldHarnessExample.d.ts +26 -0
- package/lib/examples/ShieldHarnessExample.js +51 -0
- package/lib/examples/ShieldPolicyExample.d.ts +18 -0
- package/lib/examples/ShieldPolicyExample.js +50 -0
- package/lib/examples/example-selector.js +3 -0
- package/lib/examples/exampleGroups.d.ts +1 -1
- package/lib/examples/exampleGroups.js +4 -0
- package/lib/examples/shield/shieldHarness.d.ts +14 -0
- package/lib/examples/shield/shieldHarness.js +21 -0
- package/lib/examples/shield/shieldPolicyDemo.d.ts +85 -0
- package/lib/examples/shield/shieldPolicyDemo.js +112 -0
- package/lib/specs/harnesses.d.ts +9 -1
- package/lib/specs/harnesses.js +513 -0
- package/lib/specs/policies.js +2 -1
- package/lib/specs/teams/teams.d.ts +5 -4
- package/lib/specs/teams/teams.js +84 -12
- package/lib/types/agentspecs.d.ts +47 -1
- package/lib/types/teams.d.ts +7 -1
- package/package.json +1 -1
- package/scripts/codegen/generate_harnesses.py +41 -3
- package/scripts/codegen/generate_teams.py +3 -0
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The Shield's policy, from TypeScript (SHIELD §5.1, SH-53; SH-23).
|
|
3
|
+
*
|
|
4
|
+
* An organization's document typed by `@datalayer/agent-shield` (the types
|
|
5
|
+
* generated from the schema the Python package publishes), what it decides
|
|
6
|
+
* for each class, how ACP's tool kinds are classed, the limits soft then
|
|
7
|
+
* hard, and decisions in the words `describeDecision` gives every card and
|
|
8
|
+
* row. Needs nothing running: it reads the package only.
|
|
9
|
+
*
|
|
10
|
+
* `@datalayer/agent-shield` is not on npm yet: the page reads it from the
|
|
11
|
+
* sibling checkout `ai/agent-shield` beside agent-runtimes (see
|
|
12
|
+
* `shield/shieldPolicyDemo`), and says so where it is not there.
|
|
13
|
+
*
|
|
14
|
+
* @module examples/ShieldPolicyExample
|
|
15
|
+
*/
|
|
16
|
+
import React from 'react';
|
|
17
|
+
declare const ShieldPolicyExample: React.FC;
|
|
18
|
+
export default ShieldPolicyExample;
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
/*
|
|
3
|
+
* Copyright (c) 2025-2026 Datalayer, Inc.
|
|
4
|
+
* Distributed under the terms of the Modified BSD License.
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* The Shield's policy, from TypeScript (SHIELD §5.1, SH-53; SH-23).
|
|
8
|
+
*
|
|
9
|
+
* An organization's document typed by `@datalayer/agent-shield` (the types
|
|
10
|
+
* generated from the schema the Python package publishes), what it decides
|
|
11
|
+
* for each class, how ACP's tool kinds are classed, the limits soft then
|
|
12
|
+
* hard, and decisions in the words `describeDecision` gives every card and
|
|
13
|
+
* row. Needs nothing running: it reads the package only.
|
|
14
|
+
*
|
|
15
|
+
* `@datalayer/agent-shield` is not on npm yet: the page reads it from the
|
|
16
|
+
* sibling checkout `ai/agent-shield` beside agent-runtimes (see
|
|
17
|
+
* `shield/shieldPolicyDemo`), and says so where it is not there.
|
|
18
|
+
*
|
|
19
|
+
* @module examples/ShieldPolicyExample
|
|
20
|
+
*/
|
|
21
|
+
import { useEffect, useState } from 'react';
|
|
22
|
+
import { Heading, Text } from '@primer/react';
|
|
23
|
+
import { Box } from '@datalayer/primer-addons';
|
|
24
|
+
import { ThemedProvider } from './utils/themedProvider';
|
|
25
|
+
import { AGENT_SHIELD_MISSING, ORGANIZATION_POLICY, classRows, decisionRows, kindRows, limitRows, loadAgentShield, } from './shield/shieldPolicyDemo';
|
|
26
|
+
const cell = {
|
|
27
|
+
borderBottom: '1px solid',
|
|
28
|
+
borderColor: 'border.muted',
|
|
29
|
+
py: 1,
|
|
30
|
+
pr: 3,
|
|
31
|
+
};
|
|
32
|
+
function Table({ head, rows, }) {
|
|
33
|
+
return (_jsxs(Box, { as: "table", sx: { borderCollapse: 'collapse', fontSize: 1, mb: 4 }, children: [_jsx("thead", { children: _jsx("tr", { children: head.map(title => (_jsx(Box, { as: "th", sx: { ...cell, textAlign: 'left' }, children: title }, title))) }) }), _jsx("tbody", { children: rows.map(row => (_jsx("tr", { children: row.map((value, index) => (_jsx(Box, { as: "td", sx: cell, children: value }, index))) }, row.join('|')))) })] }));
|
|
34
|
+
}
|
|
35
|
+
function Tables({ shield, }) {
|
|
36
|
+
return (_jsxs(_Fragment, { children: [_jsx(Heading, { as: "h2", sx: { fontSize: 2, mb: 2 }, children: "By class" }), _jsx(Table, { head: ['Class', `The ${ORGANIZATION_POLICY.scope}'s document says`], rows: classRows(shield).map(row => [row.actionClass, row.says]) }), _jsx(Heading, { as: "h2", sx: { fontSize: 2, mb: 2 }, children: "A coding agent's tool kinds" }), _jsx(Table, { head: ['ACP kind', 'Decided as'], rows: kindRows(shield).map(row => [row.kind, row.actionClass]) }), _jsx(Heading, { as: "h2", sx: { fontSize: 2, mb: 2 }, children: "Limits, soft then hard" }), _jsx(Table, { head: ['Limit', 'Soft: asks once', 'Hard: refuses'], rows: limitRows(shield).map(row => [row.limit, row.soft, row.hard]) }), _jsx(Heading, { as: "h2", sx: { fontSize: 2, mb: 2 }, children: "Decisions, in their words" }), _jsx(Table, { head: ['The Shield said', 'describeDecision'], rows: decisionRows(shield).map(row => [row.sentence, row.words]) })] }));
|
|
37
|
+
}
|
|
38
|
+
const ShieldPolicyExample = () => {
|
|
39
|
+
// `undefined` while reading, `null` without the sibling checkout.
|
|
40
|
+
const [shield, setShield] = useState(undefined);
|
|
41
|
+
useEffect(() => {
|
|
42
|
+
let live = true;
|
|
43
|
+
void loadAgentShield().then(loaded => live && setShield(loaded));
|
|
44
|
+
return () => {
|
|
45
|
+
live = false;
|
|
46
|
+
};
|
|
47
|
+
}, []);
|
|
48
|
+
return (_jsx(ThemedProvider, { children: _jsxs(Box, { p: 4, maxWidth: "900px", mx: "auto", "data-testid": "shield-policy-example", children: [_jsx(Heading, { as: "h1", sx: { fontSize: 4, mb: 2 }, children: "The Shield's policy, typed" }), _jsx(Text, { as: "p", sx: { color: 'fg.muted', mb: 4 }, children: "An organization's document in `@datalayer/agent-shield`'s shape, and what it decides. Three levels decide every action \u2014 the organization's, the application's, the session's \u2014 strictest first; a lower level only tightens." }), shield === undefined ? (_jsx(Text, { as: "p", children: "Reading @datalayer/agent-shield\u2026" })) : shield === null ? (_jsx(Text, { as: "p", sx: { color: 'attention.fg' }, children: AGENT_SHIELD_MISSING })) : (_jsx(Tables, { shield: shield }))] }) }));
|
|
49
|
+
};
|
|
50
|
+
export default ShieldPolicyExample;
|
|
@@ -133,6 +133,9 @@ export const EXAMPLE_ENTRIES = [
|
|
|
133
133
|
makeEntry('AgentA2ATeamExample', () => import('./AgentA2ATeamExample'), 'Two applications as a team over A2A: Sales in the browser (@a2a-js/sdk) asks Accounting on a runtime (fasta2a, Odoo read only), each an Office Assistant character.'),
|
|
134
134
|
makeEntry('ProtocolSignedRequestsExample', () => import('./ProtocolSignedRequestsExample'), 'Web Bot Auth in the browser: a key made in the page signs a request — its three headers and the signature base — verified, then a replay and a changed path refused.'),
|
|
135
135
|
makeEntry('ProtocolUcpCheckoutExample', () => import('./ProtocolUcpCheckoutExample'), 'A UCP checkout at a test store in the page: the exact purchase proposed, approved on a card once, bought once.'),
|
|
136
|
+
// The Shield (SHIELD.md SH-23): a coding agent behind it, and its policy's types.
|
|
137
|
+
makeEntry('ShieldHarnessExample', () => import('./ShieldHarnessExample'), 'A coding agent behind the Shield in the web chat: its changes as diffs, its commands as terminals, what a rule asks first in the approval banner. Needs `python examples/shield/harness_on_the_runtime.py --serve` (the fake agent, no key).', ['example', 'shield', 'harness', 'acp', 'ag-ui', 'chat']),
|
|
138
|
+
makeEntry('ShieldPolicyExample', () => import('./ShieldPolicyExample'), 'The Shield’s policy from TypeScript: an organization’s document typed by @datalayer/agent-shield, what it decides by class, the tool kinds classed, the limits soft then hard, decisions in describeDecision’s words.', ['example', 'shield', 'policy']),
|
|
136
139
|
makeEntry('PapCompanyDiscoveryExample', () => import('./PapCompanyDiscoveryExample'), 'Validate a PAP company document and reduce it to the public capabilities safe for an agent or UI.'),
|
|
137
140
|
makeEntry('PapAgentIdentityExample', () => import('./PapAgentIdentityExample'), 'Verify personal-agent client metadata and signing policy without exposing JWK coordinates.'),
|
|
138
141
|
makeEntry('PapAuthorizationBoundaryExample', () => import('./PapAuthorizationBoundaryExample'), 'Generate real Session and Direct Sign-In security material while showing only safe policy status.'),
|
|
@@ -5,5 +5,5 @@
|
|
|
5
5
|
*
|
|
6
6
|
* @module examples/exampleGroups
|
|
7
7
|
*/
|
|
8
|
-
export declare const EXAMPLE_GROUP_ORDER: readonly ["Apps", "Assistant", "A2UI", "A2A", "Personal Agent Protocol", "Agent protocols", "AG-UI", "Chat", "Document", "Notebook", "Capabilities", "Cell", "CopilotKit"];
|
|
8
|
+
export declare const EXAMPLE_GROUP_ORDER: readonly ["Apps", "Assistant", "A2UI", "A2A", "Personal Agent Protocol", "Agent protocols", "Shield", "AG-UI", "Chat", "Document", "Notebook", "Capabilities", "Cell", "CopilotKit"];
|
|
9
9
|
export declare const getExampleGroup: (id: string) => string;
|
|
@@ -16,6 +16,7 @@ export const EXAMPLE_GROUP_ORDER = [
|
|
|
16
16
|
'A2A',
|
|
17
17
|
'Personal Agent Protocol',
|
|
18
18
|
'Agent protocols',
|
|
19
|
+
'Shield',
|
|
19
20
|
'AG-UI',
|
|
20
21
|
'Chat',
|
|
21
22
|
'Document',
|
|
@@ -43,6 +44,9 @@ export const getExampleGroup = (id) => {
|
|
|
43
44
|
// The other agent protocols' examples: signed requests, commerce (AGENT_PROTOCOLS EX-10).
|
|
44
45
|
if (id.startsWith('Protocol'))
|
|
45
46
|
return 'Agent protocols';
|
|
47
|
+
// The Shield: a coding agent behind it, and its policy (SHIELD.md SH-23).
|
|
48
|
+
if (id.startsWith('Shield'))
|
|
49
|
+
return 'Shield';
|
|
46
50
|
if (id.startsWith('AgUi'))
|
|
47
51
|
return 'AG-UI';
|
|
48
52
|
if (id.startsWith('CopilotKit'))
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What `ShieldHarnessExample` connects to and offers (SHIELD SH-23).
|
|
3
|
+
*
|
|
4
|
+
* `examples/shield/harness_on_the_runtime.py --serve` names the harness's
|
|
5
|
+
* agent `chat`, as `loop --harness` does with `AGENT_RUNTIMES_AGENT_NAME`;
|
|
6
|
+
* the openers are the fake agent's words (its docstring says what each does).
|
|
7
|
+
*
|
|
8
|
+
* @module examples/shield/shieldHarness
|
|
9
|
+
*/
|
|
10
|
+
import type { Suggestion } from '../../types/chat';
|
|
11
|
+
/** The agent the local runtime serves the harness as. */
|
|
12
|
+
export declare const SHIELD_HARNESS_AGENT = "chat";
|
|
13
|
+
/** What to ask the fake agent: one of each decision. */
|
|
14
|
+
export declare const SHIELD_HARNESS_OPENERS: Suggestion[];
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) 2025-2026 Datalayer, Inc.
|
|
3
|
+
* Distributed under the terms of the Modified BSD License.
|
|
4
|
+
*/
|
|
5
|
+
/** The agent the local runtime serves the harness as. */
|
|
6
|
+
export const SHIELD_HARNESS_AGENT = 'chat';
|
|
7
|
+
/** What to ask the fake agent: one of each decision. */
|
|
8
|
+
export const SHIELD_HARNESS_OPENERS = [
|
|
9
|
+
{
|
|
10
|
+
title: 'Edit a file',
|
|
11
|
+
message: 'edit and read README.md',
|
|
12
|
+
},
|
|
13
|
+
{
|
|
14
|
+
title: 'Run a command',
|
|
15
|
+
message: 'run echo hello',
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
title: 'Read outside the workspace',
|
|
19
|
+
message: 'outside',
|
|
20
|
+
},
|
|
21
|
+
];
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What `ShieldPolicyExample` draws, as data (SHIELD §5.1, SH-53; SH-23).
|
|
3
|
+
*
|
|
4
|
+
* `@datalayer/agent-shield` is the Shield's TypeScript: the policy
|
|
5
|
+
* document's types generated from the schema the Python package publishes,
|
|
6
|
+
* the classes and the verdicts, ACP's tool kinds mapped to the classes, the
|
|
7
|
+
* limits' words, and `describeDecision` — the one place a decision's words
|
|
8
|
+
* are written. It is not on npm yet (npm's latest is an old scaffold), so
|
|
9
|
+
* agent-runtimes does not depend on it: this page reads it from the sibling
|
|
10
|
+
* checkout, `ai/agent-shield/src/policy.ts` beside `ai/agent-runtimes`, the
|
|
11
|
+
* way the monorepo lays them out — through Vite's `import.meta.glob`, which
|
|
12
|
+
* finds nothing (and the page says so) where the sibling is not there, as in
|
|
13
|
+
* agent-runtimes' own CI. The shapes below name only what the page reads;
|
|
14
|
+
* the types themselves are the package's.
|
|
15
|
+
*
|
|
16
|
+
* @module examples/shield/shieldPolicyDemo
|
|
17
|
+
*/
|
|
18
|
+
export type Verdict = 'allow' | 'ask' | 'deny';
|
|
19
|
+
/** A decision as the Shield returns it (the package's `Decision`). */
|
|
20
|
+
export type Decision = {
|
|
21
|
+
verdict: Verdict;
|
|
22
|
+
sentence: string;
|
|
23
|
+
scope?: 'organization' | 'team' | 'session' | null;
|
|
24
|
+
rule?: string | null;
|
|
25
|
+
decided_by: 'rule' | 'limit' | 'network' | 'default';
|
|
26
|
+
};
|
|
27
|
+
/** The part of a policy document the page draws (the package's `Policy`). */
|
|
28
|
+
export type PolicyDocument = {
|
|
29
|
+
scope: 'organization' | 'team' | 'session';
|
|
30
|
+
rules?: Array<{
|
|
31
|
+
name: string;
|
|
32
|
+
decision: Verdict;
|
|
33
|
+
classes?: string[];
|
|
34
|
+
commands?: string[];
|
|
35
|
+
where?: 'inside' | 'outside' | 'any';
|
|
36
|
+
reason?: string;
|
|
37
|
+
}>;
|
|
38
|
+
limits?: Record<string, {
|
|
39
|
+
soft: number;
|
|
40
|
+
hard: number;
|
|
41
|
+
} | null | undefined>;
|
|
42
|
+
harnesses?: {
|
|
43
|
+
admit?: string[];
|
|
44
|
+
credentials?: 'account' | 'platform' | 'either';
|
|
45
|
+
};
|
|
46
|
+
};
|
|
47
|
+
/** What the page reads from `@datalayer/agent-shield`'s `policy.ts`. */
|
|
48
|
+
export type AgentShieldPolicyModule = {
|
|
49
|
+
ACTION_CLASSES: readonly string[];
|
|
50
|
+
TOOL_KINDS: readonly string[];
|
|
51
|
+
KIND_CLASS: Record<string, string | null>;
|
|
52
|
+
LIMIT_NAMES: readonly string[];
|
|
53
|
+
LIMIT_WORDS: Record<string, string>;
|
|
54
|
+
VERDICT_WORDS: Record<Verdict, string>;
|
|
55
|
+
describeDecision: (decision: Decision) => string;
|
|
56
|
+
};
|
|
57
|
+
/** What the page says when the sibling checkout is not beside this one. */
|
|
58
|
+
export declare const AGENT_SHIELD_MISSING = "This page reads @datalayer/agent-shield from the sibling checkout ai/agent-shield, which is not beside this one: clone github.com/datalayer/agent-shield next to agent-runtimes (the package is not on npm yet).";
|
|
59
|
+
/** `@datalayer/agent-shield`'s policy module, or `null` without the sibling checkout. */
|
|
60
|
+
export declare function loadAgentShield(): Promise<AgentShieldPolicyModule | null>;
|
|
61
|
+
/** An organization's document, in the package's shape: what an administrator writes. */
|
|
62
|
+
export declare const ORGANIZATION_POLICY: PolicyDocument;
|
|
63
|
+
/** One row per class: what the organization's document decides for it, in words. */
|
|
64
|
+
export declare function classRows(shield: AgentShieldPolicyModule, policy?: PolicyDocument): Array<{
|
|
65
|
+
actionClass: string;
|
|
66
|
+
says: string;
|
|
67
|
+
}>;
|
|
68
|
+
/** ACP's tool kinds and the class each is decided as (§4.5). */
|
|
69
|
+
export declare function kindRows(shield: AgentShieldPolicyModule): Array<{
|
|
70
|
+
kind: string;
|
|
71
|
+
actionClass: string;
|
|
72
|
+
}>;
|
|
73
|
+
/** The limits a document sets, soft then hard, in the sentences' words. */
|
|
74
|
+
export declare function limitRows(shield: AgentShieldPolicyModule, policy?: PolicyDocument): Array<{
|
|
75
|
+
limit: string;
|
|
76
|
+
soft: string;
|
|
77
|
+
hard: string;
|
|
78
|
+
}>;
|
|
79
|
+
/** Decisions as the Shield returns them. */
|
|
80
|
+
export declare const DECISIONS: Decision[];
|
|
81
|
+
/** Each decision and its words through `describeDecision`. */
|
|
82
|
+
export declare function decisionRows(shield: AgentShieldPolicyModule): Array<{
|
|
83
|
+
sentence: string;
|
|
84
|
+
words: string;
|
|
85
|
+
}>;
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) 2025-2026 Datalayer, Inc.
|
|
3
|
+
* Distributed under the terms of the Modified BSD License.
|
|
4
|
+
*/
|
|
5
|
+
/// <reference types="vite/client" />
|
|
6
|
+
/** The sibling checkout's module, when it is there. */
|
|
7
|
+
const SIBLING = import.meta.glob('../../../../agent-shield/src/policy.ts');
|
|
8
|
+
/** What the page says when the sibling checkout is not beside this one. */
|
|
9
|
+
export const AGENT_SHIELD_MISSING = 'This page reads @datalayer/agent-shield from the sibling checkout ai/agent-shield, which is not beside this one: clone github.com/datalayer/agent-shield next to agent-runtimes (the package is not on npm yet).';
|
|
10
|
+
/** `@datalayer/agent-shield`'s policy module, or `null` without the sibling checkout. */
|
|
11
|
+
export async function loadAgentShield() {
|
|
12
|
+
const load = Object.values(SIBLING)[0];
|
|
13
|
+
return load ? load() : null;
|
|
14
|
+
}
|
|
15
|
+
/** An organization's document, in the package's shape: what an administrator writes. */
|
|
16
|
+
export const ORGANIZATION_POLICY = {
|
|
17
|
+
scope: 'organization',
|
|
18
|
+
rules: [
|
|
19
|
+
{
|
|
20
|
+
name: 'commands ask',
|
|
21
|
+
decision: 'ask',
|
|
22
|
+
classes: ['execute'],
|
|
23
|
+
reason: 'a person sees every command first',
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
name: 'nothing deleted outside',
|
|
27
|
+
decision: 'deny',
|
|
28
|
+
classes: ['delete'],
|
|
29
|
+
where: 'outside',
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
name: 'no pushes',
|
|
33
|
+
decision: 'deny',
|
|
34
|
+
commands: ['git push*'],
|
|
35
|
+
},
|
|
36
|
+
],
|
|
37
|
+
limits: {
|
|
38
|
+
tool_calls: { soft: 200, hard: 400 },
|
|
39
|
+
model_tokens: { soft: 200000, hard: 500000 },
|
|
40
|
+
spend: { soft: 500, hard: 1000 },
|
|
41
|
+
},
|
|
42
|
+
harnesses: { admit: ['claude-code', 'codex'], credentials: 'account' },
|
|
43
|
+
};
|
|
44
|
+
/** One row per class: what the organization's document decides for it, in words. */
|
|
45
|
+
export function classRows(shield, policy = ORGANIZATION_POLICY) {
|
|
46
|
+
return shield.ACTION_CLASSES.map(actionClass => {
|
|
47
|
+
const rule = (policy.rules ?? []).find(item => (item.classes ?? []).includes(actionClass));
|
|
48
|
+
return {
|
|
49
|
+
actionClass,
|
|
50
|
+
says: rule
|
|
51
|
+
? `${shield.VERDICT_WORDS[rule.decision]} — '${rule.name}'${rule.where && rule.where !== 'any' ? ` (${rule.where} the workspace)` : ''}`
|
|
52
|
+
: 'nothing said: the next level decides',
|
|
53
|
+
};
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
/** ACP's tool kinds and the class each is decided as (§4.5). */
|
|
57
|
+
export function kindRows(shield) {
|
|
58
|
+
return shield.TOOL_KINDS.map(kind => ({
|
|
59
|
+
kind,
|
|
60
|
+
actionClass: shield.KIND_CLASS[kind] ?? 'nothing to decide',
|
|
61
|
+
}));
|
|
62
|
+
}
|
|
63
|
+
/** The limits a document sets, soft then hard, in the sentences' words. */
|
|
64
|
+
export function limitRows(shield, policy = ORGANIZATION_POLICY) {
|
|
65
|
+
return shield.LIMIT_NAMES.flatMap(name => {
|
|
66
|
+
const threshold = policy.limits?.[name];
|
|
67
|
+
return threshold
|
|
68
|
+
? [
|
|
69
|
+
{
|
|
70
|
+
limit: shield.LIMIT_WORDS[name],
|
|
71
|
+
soft: String(threshold.soft),
|
|
72
|
+
hard: String(threshold.hard),
|
|
73
|
+
},
|
|
74
|
+
]
|
|
75
|
+
: [];
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
/** Decisions as the Shield returns them. */
|
|
79
|
+
export const DECISIONS = [
|
|
80
|
+
{
|
|
81
|
+
verdict: 'allow',
|
|
82
|
+
sentence: 'Edit main.py: do it',
|
|
83
|
+
scope: 'session',
|
|
84
|
+
rule: 'edit and move inside the workspace',
|
|
85
|
+
decided_by: 'rule',
|
|
86
|
+
},
|
|
87
|
+
{
|
|
88
|
+
verdict: 'ask',
|
|
89
|
+
sentence: 'Run `pytest`: ask me first',
|
|
90
|
+
scope: 'organization',
|
|
91
|
+
rule: 'commands ask',
|
|
92
|
+
decided_by: 'rule',
|
|
93
|
+
},
|
|
94
|
+
{
|
|
95
|
+
verdict: 'deny',
|
|
96
|
+
sentence: 'a model request: refused',
|
|
97
|
+
scope: 'organization',
|
|
98
|
+
decided_by: 'limit',
|
|
99
|
+
},
|
|
100
|
+
{
|
|
101
|
+
verdict: 'ask',
|
|
102
|
+
sentence: 'Fetch https://example.com/: ask me first',
|
|
103
|
+
decided_by: 'default',
|
|
104
|
+
},
|
|
105
|
+
];
|
|
106
|
+
/** Each decision and its words through `describeDecision`. */
|
|
107
|
+
export function decisionRows(shield) {
|
|
108
|
+
return DECISIONS.map(decision => ({
|
|
109
|
+
sentence: decision.sentence,
|
|
110
|
+
words: shield.describeDecision(decision),
|
|
111
|
+
}));
|
|
112
|
+
}
|
package/lib/specs/harnesses.d.ts
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
* This file is AUTO-GENERATED from YAML specifications.
|
|
7
7
|
* DO NOT EDIT MANUALLY - run 'make specs' to regenerate.
|
|
8
8
|
*/
|
|
9
|
-
import type { HarnessSpec } from '../types/agentspecs';
|
|
9
|
+
import type { HarnessSpec, ListedHarness } from '../types/agentspecs';
|
|
10
10
|
export declare const CLAUDE_CODE_HARNESS_0_0_1: HarnessSpec;
|
|
11
11
|
export declare const CODEX_HARNESS_0_0_1: HarnessSpec;
|
|
12
12
|
export declare const CUSTOM_HARNESS_0_0_1: HarnessSpec;
|
|
@@ -20,3 +20,11 @@ export declare const HARNESS_CATALOGUE: Record<string, HarnessSpec>;
|
|
|
20
20
|
export declare function getHarness(harnessId: string): HarnessSpec | undefined;
|
|
21
21
|
/** Every harness of the catalogue. */
|
|
22
22
|
export declare function listHarnesses(): HarnessSpec[];
|
|
23
|
+
/**
|
|
24
|
+
* The register's listed tier (SH-57): agents known to speak ACP, registered
|
|
25
|
+
* with their documented command and their terms, not drilled — offered by
|
|
26
|
+
* nothing until moved to the catalogue.
|
|
27
|
+
*/
|
|
28
|
+
export declare const LISTED_HARNESSES: ListedHarness[];
|
|
29
|
+
/** The sentence a listed harness is refused in (agentspecs' LISTED_NOT_DRILLED). */
|
|
30
|
+
export declare const LISTED_NOT_DRILLED = "listed, not drilled yet";
|