@ziggs-ai/agent-sdk 0.12.0 → 0.14.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/dist/AgentHost.js +4 -1
- package/dist/agent/ClaudeSdkAgent.js +2 -2
- package/dist/agent/claudeCognition.js +12 -0
- package/dist/agent/claudeSdkTools.js +5 -1
- package/dist/cognition/validateContext.js +4 -1
- package/dist/context/batch.d.ts +3 -0
- package/dist/context/batch.js +8 -5
- package/dist/context/classifyEnvelope.js +4 -5
- package/dist/context/routingLabels.js +2 -3
- package/dist/formatters/AgreementFormatter.d.ts +7 -1
- package/dist/formatters/AgreementFormatter.js +17 -8
- package/dist/formatters/HistoryFormatter.d.ts +5 -0
- package/dist/formatters/HistoryFormatter.js +16 -7
- package/dist/index.d.ts +2 -1
- package/dist/index.js +2 -1
- package/dist/ingress/normalizeIncoming.d.ts +3 -8
- package/dist/pricing/fleetDefaults.d.ts +0 -1
- package/dist/pricing/fleetDefaults.js +7 -12
- package/dist/runtime/PromptBuilder.js +19 -21
- package/dist/runtime/buildOutcome.js +4 -4
- package/dist/runtime/kickoff.d.ts +17 -4
- package/dist/runtime/kickoff.js +55 -15
- package/dist/runtime/mandateDeclaration.d.ts +9 -0
- package/dist/runtime/mandateDeclaration.js +62 -0
- package/dist/runtime/runTurn.js +8 -0
- package/dist/server/agreements/AgreementService.d.ts +14 -12
- package/dist/server/agreements/AgreementService.js +15 -15
- package/dist/server/inboxLoop.js +19 -0
- package/dist/server/proactive/ProactiveTrigger.d.ts +7 -1
- package/dist/server/proactive/ProactiveTrigger.js +2 -2
- package/dist/server/tools/index.d.ts +1 -1
- package/dist/server/tools/index.js +1 -1
- package/dist/server/tools/tier1/protocolRunner.js +14 -8
- package/dist/server/tools/tier1/protocolTools.js +8 -3
- package/dist/server/tools/tier2/linkTools.d.ts +1 -1
- package/dist/server/tools/tier2/linkTools.js +11 -9
- package/dist/tools/capabilityAdapter.js +10 -7
- package/dist/tools/toolCreds.d.ts +37 -0
- package/dist/tools/toolCreds.js +49 -0
- package/dist/types.d.ts +2 -6
- package/package.json +2 -2
package/dist/AgentHost.js
CHANGED
|
@@ -201,11 +201,13 @@ export class AgentHost {
|
|
|
201
201
|
description: resolved.description || 'A helpful assistant',
|
|
202
202
|
systemPrompt: resolved.systemPrompt,
|
|
203
203
|
specialization: resolved.specialization ?? null,
|
|
204
|
+
requestMatchTags: resolved.requestMatchTags,
|
|
204
205
|
tools: resolved.tools || [],
|
|
205
206
|
// Copied deliberately: this object is an allow-list, so a field left out
|
|
206
207
|
// here is silently dropped between the manifest and the runtime. That is
|
|
207
208
|
// exactly how `respondsToProposals` reached the store as null for 133
|
|
208
|
-
// agents — the declaration existed and nothing carried it.
|
|
209
|
+
// agents — the declaration existed and nothing carried it. Same for
|
|
210
|
+
// `requestMatchTags` (always undefined at triage) and `telemetryIngest`.
|
|
209
211
|
needs: resolved.needs,
|
|
210
212
|
taskTools: resolved.taskTools,
|
|
211
213
|
states: resolved.states,
|
|
@@ -219,6 +221,7 @@ export class AgentHost {
|
|
|
219
221
|
metricsTap: resolved.metricsTap,
|
|
220
222
|
wakeTap: resolved.wakeTap,
|
|
221
223
|
inboxCatchUp: resolved.inboxCatchUp,
|
|
224
|
+
telemetryIngest: resolved.telemetryIngest,
|
|
222
225
|
brain: resolved.brain,
|
|
223
226
|
cognition: resolved.cognition ?? 'fsm',
|
|
224
227
|
claudeMaxTurns: resolved.claudeMaxTurns,
|
|
@@ -197,8 +197,8 @@ function resolveOnBehalfAgreementId(rawEvent, contextSnap, agentId, sessionId) {
|
|
|
197
197
|
? contextSnap.agreements
|
|
198
198
|
: [];
|
|
199
199
|
const provides = ags.filter((a) => {
|
|
200
|
-
const
|
|
201
|
-
const providerIds = [
|
|
200
|
+
const provider = a?.parties?.provider;
|
|
201
|
+
const providerIds = [provider?.actor, a?.providerId, a?.providerAgentId, a?.executorId];
|
|
202
202
|
const isProvider = providerIds.some((x) => x === agentId);
|
|
203
203
|
const status = a?.status != null ? String(a.status).toLowerCase() : '';
|
|
204
204
|
const active = !status || status === 'active' || status === 'approved';
|
|
@@ -151,6 +151,18 @@ function renderEventLines(event, lines) {
|
|
|
151
151
|
lines.push(`Agreement: ${agreementId}`);
|
|
152
152
|
}
|
|
153
153
|
}
|
|
154
|
+
// The other side of the same policy: a message this agent sent to a
|
|
155
|
+
// published agent landed and was NOT rung through. Nothing is wrong and
|
|
156
|
+
// nothing is lost, so this must not read as a refusal — but without it the
|
|
157
|
+
// sender waits on a reply that is never coming and its rational next move
|
|
158
|
+
// is to send again.
|
|
159
|
+
if (reason === 'contact_policy_withheld') {
|
|
160
|
+
lines.push('Your message was delivered and is readable, but the agent you wrote ' +
|
|
161
|
+
'to is not woken for it: its listing is claim-first, so it starts ' +
|
|
162
|
+
'work once you claim the listing. Do not resend — claim the listing ' +
|
|
163
|
+
'(ziggs_marketplace_view to find it, then ziggs_agreement_claim), or ' +
|
|
164
|
+
'wait if somebody else is claiming on your behalf.');
|
|
165
|
+
}
|
|
154
166
|
}
|
|
155
167
|
if (typeof event?.agreementId === 'string' && event.agreementId) {
|
|
156
168
|
lines.push(`Agreement: ${event.agreementId}`);
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { randomUUID } from 'node:crypto';
|
|
2
|
+
import { laneFromToolContext } from '../tools/toolCreds.js';
|
|
2
3
|
import { listTasks } from '@ziggs-ai/api-client';
|
|
3
4
|
import { defineTool } from '../tools/defineTool.js';
|
|
4
5
|
import { listGrantsTool } from '../server/tools/tier2/grantsTools.js';
|
|
@@ -177,7 +178,10 @@ export const listTasksTool = defineTool('task_list', {
|
|
|
177
178
|
const createdBy = args.createdByMe ? c.agentId : undefined;
|
|
178
179
|
// the lane fences this to the engagement's tasks. Without it the
|
|
179
180
|
// list is every task the agent's key can reach, across all its customers.
|
|
180
|
-
|
|
181
|
+
// One reader for the lane, shared with the capability adapter and with
|
|
182
|
+
// hand-written tools — three copies of `chatId || sessionId` is how one of
|
|
183
|
+
// them ends up not claiming the reach the fence exists to grant.
|
|
184
|
+
const laneId = laneFromToolContext(c);
|
|
181
185
|
return listTasks({
|
|
182
186
|
state: args.state,
|
|
183
187
|
cursor: args.cursor,
|
|
@@ -41,8 +41,11 @@ function validateAgreements(agreements, warn) {
|
|
|
41
41
|
}
|
|
42
42
|
if (ag['parties'] && typeof ag['parties'] === 'object') {
|
|
43
43
|
const parties = ag['parties'];
|
|
44
|
+
// Each side is occupied when either column names somebody; a side with a
|
|
45
|
+
// principal and no actor is a party acting through its own credential.
|
|
44
46
|
for (const key of ['creator', 'provider']) {
|
|
45
|
-
|
|
47
|
+
const side = parties[key];
|
|
48
|
+
if (!side?.principal && !side?.actor)
|
|
46
49
|
warn(`${path}.parties.${key}`, 'missing');
|
|
47
50
|
}
|
|
48
51
|
}
|
package/dist/context/batch.d.ts
CHANGED
|
@@ -1,2 +1,5 @@
|
|
|
1
|
+
import { type AgreementParties } from '@ziggs-ai/api-client';
|
|
1
2
|
export declare function getBatchEvents(rawEvent: unknown): unknown[];
|
|
2
3
|
export declare function isTaskResultRelevantToAgent(result: Record<string, unknown>, ownAgentId: string | null): boolean;
|
|
4
|
+
/** The agreement's party slots on a task_result payload, when it carries one. */
|
|
5
|
+
export declare function partiesOf(result: Record<string, unknown>): AgreementParties | undefined;
|
package/dist/context/batch.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { isBroadcastTarget } from '@ziggs-ai/api-client';
|
|
1
|
+
import { isBroadcastTarget, partyActorIds } from '@ziggs-ai/api-client';
|
|
2
2
|
export function getBatchEvents(rawEvent) {
|
|
3
3
|
if (!rawEvent)
|
|
4
4
|
return [];
|
|
@@ -10,9 +10,12 @@ export function getBatchEvents(rawEvent) {
|
|
|
10
10
|
export function isTaskResultRelevantToAgent(result, ownAgentId) {
|
|
11
11
|
if (!ownAgentId)
|
|
12
12
|
return true;
|
|
13
|
-
const parties = result
|
|
13
|
+
const parties = partiesOf(result);
|
|
14
14
|
return !!(result['creatorIsYou'] || result['providerIsYou'] || result['payerIsYou'] || result['proposedToIsYou'] ||
|
|
15
|
-
parties
|
|
16
|
-
parties
|
|
17
|
-
|
|
15
|
+
partyActorIds(parties).includes(ownAgentId) ||
|
|
16
|
+
isBroadcastTarget(parties?.proposedTo?.principal));
|
|
17
|
+
}
|
|
18
|
+
/** The agreement's party slots on a task_result payload, when it carries one. */
|
|
19
|
+
export function partiesOf(result) {
|
|
20
|
+
return result['agreement']?.parties;
|
|
18
21
|
}
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import { CONTEXT_RESET } from './applyEffects.js';
|
|
2
|
-
import { getBatchEvents, isTaskResultRelevantToAgent } from './batch.js';
|
|
2
|
+
import { getBatchEvents, isTaskResultRelevantToAgent, partiesOf } from './batch.js';
|
|
3
3
|
function isTaskAssignment(result, ownAgentId) {
|
|
4
|
-
const
|
|
5
|
-
const isProvider = result['providerIsYou'] || parties['provider'] === ownAgentId;
|
|
4
|
+
const isProvider = result['providerIsYou'] || partiesOf(result)?.provider?.actor === ownAgentId;
|
|
6
5
|
return !!(isProvider && (result['state'] === 'active' || result['state'] === 'in-progress'));
|
|
7
6
|
}
|
|
8
7
|
export function classifyIncomingEvent(rawEvent, ownAgentId) {
|
|
@@ -22,9 +21,9 @@ export function classifyIncomingEvent(rawEvent, ownAgentId) {
|
|
|
22
21
|
continue;
|
|
23
22
|
const state = result['state'];
|
|
24
23
|
const ag = result['agreement'];
|
|
25
|
-
const parties =
|
|
24
|
+
const parties = partiesOf(result);
|
|
26
25
|
const proposalStatus = ag?.['proposal']?.['status'];
|
|
27
|
-
if (state === 'active' && proposalStatus === 'approved' && ownAgentId && parties
|
|
26
|
+
if (state === 'active' && proposalStatus === 'approved' && ownAgentId && parties?.creator?.actor === ownAgentId) {
|
|
28
27
|
flags['approval'] = true;
|
|
29
28
|
flags['taskAssignment'] = result;
|
|
30
29
|
continue;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { isProtocolToolName } from '../tasks/protocolRegistry.js';
|
|
2
|
-
import { getBatchEvents, isTaskResultRelevantToAgent } from './batch.js';
|
|
2
|
+
import { getBatchEvents, isTaskResultRelevantToAgent, partiesOf } from './batch.js';
|
|
3
3
|
export function unwrapBatchEvent(event) {
|
|
4
4
|
const e = event;
|
|
5
5
|
if (e?.['type'] === 'batch' && Array.isArray(e['events']) && e['events'][0])
|
|
@@ -22,9 +22,8 @@ export function classifyWorkflowEvent(event, ownAgentId = null) {
|
|
|
22
22
|
sawOwnTaskResult = true;
|
|
23
23
|
const state = result['state'];
|
|
24
24
|
const ag = result['agreement'];
|
|
25
|
-
const parties = ag?.['parties'] || {};
|
|
26
25
|
const proposalStatus = ag?.['proposal'] ? ag['proposal']['status'] : undefined;
|
|
27
|
-
const isProvider = result['providerIsYou'] ||
|
|
26
|
+
const isProvider = result['providerIsYou'] || partiesOf(result)?.provider?.actor === ownAgentId;
|
|
28
27
|
if (isProvider && (state === 'active' || state === 'in-progress'))
|
|
29
28
|
return 'task_assignment';
|
|
30
29
|
if (proposalStatus === 'approved' || (state === 'active' && proposalStatus === 'pending'))
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { type AgreementPartySide } from '@ziggs-ai/api-client';
|
|
1
2
|
interface AgreementFormatterOptions {
|
|
2
3
|
shortIds?: boolean;
|
|
3
4
|
indentSize?: number;
|
|
@@ -10,7 +11,12 @@ export declare class AgreementFormatter {
|
|
|
10
11
|
format(agreements: AnyObj[] | null | undefined): string;
|
|
11
12
|
formatAgreement(ag: AnyObj, indent?: string): string;
|
|
12
13
|
_renderTaskExecution(task: AnyObj, indent?: string): string;
|
|
13
|
-
|
|
14
|
+
/**
|
|
15
|
+
* A side names up to two ids — the accountable principal and the agent that
|
|
16
|
+
* acted for it. Both are rendered: the agent has to recognize itself here,
|
|
17
|
+
* and the principal is who the deal is actually with.
|
|
18
|
+
*/
|
|
19
|
+
_labelParty(side: AgreementPartySide | null | undefined, isYou: boolean | undefined): string;
|
|
14
20
|
shortId(id: string | null | undefined): string;
|
|
15
21
|
private _indent;
|
|
16
22
|
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { partySideIds } from '@ziggs-ai/api-client';
|
|
1
2
|
export class AgreementFormatter {
|
|
2
3
|
shortIds;
|
|
3
4
|
indentSize;
|
|
@@ -37,14 +38,16 @@ export class AgreementFormatter {
|
|
|
37
38
|
const status = (ag['status'] || 'unknown').toUpperCase();
|
|
38
39
|
const agId = this.shortId(ag['agreementId']);
|
|
39
40
|
const parties = ag['parties'] || {};
|
|
41
|
+
const side = (name) => parties[name];
|
|
40
42
|
const lines = [
|
|
41
43
|
`${indent}[${status}] Agreement ${agId}`,
|
|
42
|
-
`${indent} Creator: ${this._labelParty(
|
|
43
|
-
`${indent} Provider: ${this._labelParty(
|
|
44
|
-
`${indent} Payer: ${this._labelParty(
|
|
44
|
+
`${indent} Creator: ${this._labelParty(side('creator'), ag['creatorIsYou'])}`,
|
|
45
|
+
`${indent} Provider: ${this._labelParty(side('provider'), ag['providerIsYou'])}`,
|
|
46
|
+
`${indent} Payer: ${this._labelParty(side('payer'), ag['payerIsYou'])}`,
|
|
45
47
|
];
|
|
46
|
-
if (
|
|
47
|
-
lines.push(`${indent} Proposed to: ${this._labelParty(
|
|
48
|
+
if (partySideIds(side('proposedTo')).length > 0) {
|
|
49
|
+
lines.push(`${indent} Proposed to: ${this._labelParty(side('proposedTo'), ag['proposedToIsYou'])}`);
|
|
50
|
+
}
|
|
48
51
|
const proposal = ag['proposal'];
|
|
49
52
|
if (proposal?.['status'])
|
|
50
53
|
lines.push(`${indent} Proposal: ${proposal['status']}${proposal['respondedBy'] ? ` (by ${proposal['respondedBy']})` : ''}`);
|
|
@@ -111,10 +114,16 @@ export class AgreementFormatter {
|
|
|
111
114
|
}
|
|
112
115
|
return lines.join('\n');
|
|
113
116
|
}
|
|
114
|
-
|
|
115
|
-
|
|
117
|
+
/**
|
|
118
|
+
* A side names up to two ids — the accountable principal and the agent that
|
|
119
|
+
* acted for it. Both are rendered: the agent has to recognize itself here,
|
|
120
|
+
* and the principal is who the deal is actually with.
|
|
121
|
+
*/
|
|
122
|
+
_labelParty(side, isYou) {
|
|
123
|
+
const shown = partySideIds(side).join(' via ');
|
|
124
|
+
if (!shown)
|
|
116
125
|
return 'N/A';
|
|
117
|
-
return isYou ? `You (${
|
|
126
|
+
return isYou ? `You (${shown})` : shown;
|
|
118
127
|
}
|
|
119
128
|
shortId(id) {
|
|
120
129
|
if (!id)
|
|
@@ -17,6 +17,11 @@ export declare class HistoryFormatter {
|
|
|
17
17
|
formatParticipant(participant: AnyObj | null | undefined, agentId: string): string;
|
|
18
18
|
formatOwner(task: AnyObj, agentId: string): string;
|
|
19
19
|
formatExecutor(task: AnyObj, agentId: string): string;
|
|
20
|
+
/**
|
|
21
|
+
* One side of the task's agreement, or `fallback` when the frame carries no
|
|
22
|
+
* parties — a bare resource_changed skeleton has the task ids and nothing else.
|
|
23
|
+
*/
|
|
24
|
+
private _formatSide;
|
|
20
25
|
shortId(id: string | null | undefined): string;
|
|
21
26
|
formatTime(timestamp: string | null | undefined): string;
|
|
22
27
|
formatArgs(args: AnyObj | null | undefined): string;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { partySideIds } from '@ziggs-ai/api-client';
|
|
1
2
|
export class HistoryFormatter {
|
|
2
3
|
showTimestamps;
|
|
3
4
|
shortIds;
|
|
@@ -67,7 +68,8 @@ export class HistoryFormatter {
|
|
|
67
68
|
case 'created': {
|
|
68
69
|
const ag = task['agreement'];
|
|
69
70
|
const parties = ag?.['parties'] || {};
|
|
70
|
-
|
|
71
|
+
const proposedTo = partySideIds(parties['proposedTo']).join(' via ');
|
|
72
|
+
return `${timePrefix}Task created under agreement: "${desc}" (${ids})\n Owner: ${this.formatOwner(task, agentId)}\n Executor: ${this.formatExecutor(task, agentId)}\n Proposed to: ${proposedTo || 'N/A'}`;
|
|
71
73
|
}
|
|
72
74
|
case 'state_changed': {
|
|
73
75
|
const prev = service?.['previousState']?.['state'] || '?';
|
|
@@ -140,14 +142,21 @@ export class HistoryFormatter {
|
|
|
140
142
|
return `${id} (${participant['type'] || 'unknown'})`;
|
|
141
143
|
}
|
|
142
144
|
formatOwner(task, agentId) {
|
|
143
|
-
|
|
144
|
-
const creatorId = ag?.['parties']?.['creator'] ?? task['agentId'];
|
|
145
|
-
return creatorId === agentId ? 'You' : String(creatorId ?? 'N/A');
|
|
145
|
+
return this._formatSide(task, 'creator', task['agentId'], agentId);
|
|
146
146
|
}
|
|
147
147
|
formatExecutor(task, agentId) {
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
148
|
+
return this._formatSide(task, 'provider', task['executorId'], agentId);
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* One side of the task's agreement, or `fallback` when the frame carries no
|
|
152
|
+
* parties — a bare resource_changed skeleton has the task ids and nothing else.
|
|
153
|
+
*/
|
|
154
|
+
_formatSide(task, role, fallback, agentId) {
|
|
155
|
+
const parties = task['agreement']?.['parties'];
|
|
156
|
+
const ids = partySideIds(parties?.[role]);
|
|
157
|
+
if (ids.length === 0)
|
|
158
|
+
return fallback === agentId ? 'You' : String(fallback ?? 'N/A');
|
|
159
|
+
return ids.includes(agentId) ? 'You' : ids.join(' via ');
|
|
151
160
|
}
|
|
152
161
|
shortId(id) {
|
|
153
162
|
if (!id)
|
package/dist/index.d.ts
CHANGED
|
@@ -53,6 +53,7 @@ export { ToolManager } from './tools/ToolManager.js';
|
|
|
53
53
|
export { ToolProvider } from './tools/ToolProvider.js';
|
|
54
54
|
export { defineTool } from './tools/defineTool.js';
|
|
55
55
|
export { recordReport } from './tools/recordReport.js';
|
|
56
|
+
export { credsFromToolContext, laneFromToolContext } from './tools/toolCreds.js';
|
|
56
57
|
export type { RecordReportInput, RecordReportResult, TaskReport } from './tools/recordReport.js';
|
|
57
58
|
export { MCP_PROVIDER, describeNeed, normalizeNeeds, toolsForNeed, toolsForNeeds, unmetNeeds, unmetNeedsMessage, } from './tools/needs.js';
|
|
58
59
|
export type { AgentNeed, ConnectionNeed } from './tools/needs.js';
|
|
@@ -62,7 +63,7 @@ export { HistoryFormatter, historyFormatter, AgreementFormatter, agreementFormat
|
|
|
62
63
|
export { ProactiveTrigger } from './server/proactive/ProactiveTrigger.js';
|
|
63
64
|
export { PollRegistry, declaredPolls, type PollBinding, type PollContext, type PollKind, type PollResult, } from './server/polls/PollKind.js';
|
|
64
65
|
export { PollRunner, type PollRunnerOptions, type WakeTarget } from './server/polls/PollRunner.js';
|
|
65
|
-
export { PROTOCOL_TOOLS, agreementProposeTool, agreementSubcontractTool, agreementRespondTool, agreementClaimTool, agreementCounterTool, agreementGetTool, agreementRevokeTool, agreementFulfillTool, taskCreateTool, taskSetResultTool, taskUpdatePlanStepTool, dispatchProtocolOp, PAYMENT_TOOLS, paymentBalanceTool, CONNECTION_TOOLS, connectionProxyTool, connectionListGrantsTool, requestConnectionTool, MCP_CONNECTION_TOOLS, mcpToolCallTool, mcpToolsListTool, DISCOVERY_TOOLS, agentSearchTool, agentGetTool, MARKETPLACE_TOOLS, marketplaceViewTool, CONTEXT_TOOLS, contextReadTool, contextDelegateTool, contextExpandReachTool, contextDiscoverGrantableTool, GRANTS_TOOLS, listGrantsTool, LINK_TOOLS,
|
|
66
|
+
export { PROTOCOL_TOOLS, agreementProposeTool, agreementSubcontractTool, agreementRespondTool, agreementClaimTool, agreementCounterTool, agreementGetTool, agreementRevokeTool, agreementFulfillTool, taskCreateTool, taskSetResultTool, taskUpdatePlanStepTool, dispatchProtocolOp, PAYMENT_TOOLS, paymentBalanceTool, CONNECTION_TOOLS, connectionProxyTool, connectionListGrantsTool, requestConnectionTool, MCP_CONNECTION_TOOLS, mcpToolCallTool, mcpToolsListTool, DISCOVERY_TOOLS, agentSearchTool, agentGetTool, MARKETPLACE_TOOLS, marketplaceViewTool, CONTEXT_TOOLS, contextReadTool, contextDelegateTool, contextExpandReachTool, contextDiscoverGrantableTool, GRANTS_TOOLS, listGrantsTool, LINK_TOOLS, linkProposeTool, linkListTool, ARTIFACT_TOOLS, recordArtifactTool, CHAT_TOOLS, openConversationTool, } from './server/tools/index.js';
|
|
66
67
|
export { CLAUDE_SDK_TOOLS } from './agent/claudeSdkTools.js';
|
|
67
68
|
export { PROTOCOL_TOOL_NAMES, PROTOCOL_TOOL_TO_OPERATION, mapProtocolToolToOperation, isProtocolToolName } from './tasks/protocolRegistry.js';
|
|
68
69
|
export { InMemoryStore, FileMemoryStore } from './memory/MemoryStore.js';
|
package/dist/index.js
CHANGED
|
@@ -55,6 +55,7 @@ export { ToolManager } from './tools/ToolManager.js';
|
|
|
55
55
|
export { ToolProvider } from './tools/ToolProvider.js';
|
|
56
56
|
export { defineTool } from './tools/defineTool.js';
|
|
57
57
|
export { recordReport } from './tools/recordReport.js';
|
|
58
|
+
export { credsFromToolContext, laneFromToolContext } from './tools/toolCreds.js';
|
|
58
59
|
// An agent declares the access it cannot work without, and the declaration
|
|
59
60
|
// produces the tools for it.
|
|
60
61
|
export { MCP_PROVIDER, describeNeed, normalizeNeeds, toolsForNeed, toolsForNeeds, unmetNeeds, unmetNeedsMessage, } from './tools/needs.js';
|
|
@@ -76,7 +77,7 @@ export {
|
|
|
76
77
|
// Tier 1 — protocol grammar (framework-managed via taskTools).
|
|
77
78
|
PROTOCOL_TOOLS, agreementProposeTool, agreementSubcontractTool, agreementRespondTool, agreementClaimTool, agreementCounterTool, agreementGetTool, agreementRevokeTool, agreementFulfillTool, taskCreateTool, taskSetResultTool, taskUpdatePlanStepTool, dispatchProtocolOp,
|
|
78
79
|
// Tier 2 — opt-in capability bundles (spread into `tools:`).
|
|
79
|
-
PAYMENT_TOOLS, paymentBalanceTool, CONNECTION_TOOLS, connectionProxyTool, connectionListGrantsTool, requestConnectionTool, MCP_CONNECTION_TOOLS, mcpToolCallTool, mcpToolsListTool, DISCOVERY_TOOLS, agentSearchTool, agentGetTool, MARKETPLACE_TOOLS, marketplaceViewTool, CONTEXT_TOOLS, contextReadTool, contextDelegateTool, contextExpandReachTool, contextDiscoverGrantableTool, GRANTS_TOOLS, listGrantsTool, LINK_TOOLS,
|
|
80
|
+
PAYMENT_TOOLS, paymentBalanceTool, CONNECTION_TOOLS, connectionProxyTool, connectionListGrantsTool, requestConnectionTool, MCP_CONNECTION_TOOLS, mcpToolCallTool, mcpToolsListTool, DISCOVERY_TOOLS, agentSearchTool, agentGetTool, MARKETPLACE_TOOLS, marketplaceViewTool, CONTEXT_TOOLS, contextReadTool, contextDelegateTool, contextExpandReachTool, contextDiscoverGrantableTool, GRANTS_TOOLS, listGrantsTool, LINK_TOOLS, linkProposeTool, linkListTool, ARTIFACT_TOOLS, recordArtifactTool, CHAT_TOOLS, openConversationTool, } from './server/tools/index.js';
|
|
80
81
|
// The always-on toolset for the hosted Claude cognition (parity guard
|
|
81
82
|
// reads this as part of the real SDK registry).
|
|
82
83
|
export { CLAUDE_SDK_TOOLS } from './agent/claudeSdkTools.js';
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { AgreementParties } from '@ziggs-ai/api-client';
|
|
1
2
|
export interface NormalizedEvent {
|
|
2
3
|
chatId: string | null;
|
|
3
4
|
event: {
|
|
@@ -25,12 +26,6 @@ export interface NormalizedEvent {
|
|
|
25
26
|
text?: string;
|
|
26
27
|
};
|
|
27
28
|
}
|
|
28
|
-
interface WireParties {
|
|
29
|
-
creator?: string;
|
|
30
|
-
provider?: string;
|
|
31
|
-
payer?: string;
|
|
32
|
-
proposedTo?: string;
|
|
33
|
-
}
|
|
34
29
|
interface WireTask {
|
|
35
30
|
taskId?: string;
|
|
36
31
|
agentId?: string;
|
|
@@ -42,7 +37,7 @@ interface WireTask {
|
|
|
42
37
|
state?: string;
|
|
43
38
|
proposal?: unknown;
|
|
44
39
|
agreement?: {
|
|
45
|
-
parties?:
|
|
40
|
+
parties?: AgreementParties;
|
|
46
41
|
};
|
|
47
42
|
}
|
|
48
43
|
interface WireMetadata {
|
|
@@ -69,7 +64,7 @@ interface WireMetadata {
|
|
|
69
64
|
proposal?: {
|
|
70
65
|
status?: string;
|
|
71
66
|
};
|
|
72
|
-
parties?:
|
|
67
|
+
parties?: AgreementParties;
|
|
73
68
|
approvals?: Array<{
|
|
74
69
|
partyId?: string;
|
|
75
70
|
status?: string;
|
|
@@ -8,7 +8,6 @@ export declare const TIER_PRICE_CENTS: Record<FleetPricingTier, number>;
|
|
|
8
8
|
export declare function resolveFleetTier(agentId: string): FleetPricingTier | null;
|
|
9
9
|
export declare function isFirstPartyFleetAgent(agentId: string): boolean;
|
|
10
10
|
export declare function tierPriceCents(tier: FleetPricingTier): number;
|
|
11
|
-
export declare function isZiggsOrchestrator(agentId: string): boolean;
|
|
12
11
|
export declare function isFreeAllowlistedExecutor(executorId: string, description?: string | null): boolean;
|
|
13
12
|
export declare function resolveDefaultPriceCentsForExecutor(executorId: string, description?: string | null): number | null;
|
|
14
13
|
export interface ProtocolPricingPayload {
|
|
@@ -12,7 +12,6 @@ export const TIER_PRICE_CENTS = {
|
|
|
12
12
|
C: 1500, // 15 ZIG / job (orchestrator, charged once at top)
|
|
13
13
|
D: 100, // 1 ZIG / call (hand-written demo agents)
|
|
14
14
|
};
|
|
15
|
-
const ZIGGS_ORCHESTRATOR_IDS = new Set(['ziggs-agent']);
|
|
16
15
|
const PING_DESCRIPTION_PATTERN = /\b(ping|health\s*check|healthcheck|liveness|readiness|heartbeat)\b/i;
|
|
17
16
|
const TRIVIAL_LOOKUP_DESCRIPTION_PATTERN = /\b(what\s+time|current\s+time|local\s+time|world\s+clock|timezone|time\s+zone|weather|forecast|temperature|uv\s+index)\b/i;
|
|
18
17
|
export function resolveFleetTier(agentId) {
|
|
@@ -26,9 +25,6 @@ export function isFirstPartyFleetAgent(agentId) {
|
|
|
26
25
|
export function tierPriceCents(tier) {
|
|
27
26
|
return TIER_PRICE_CENTS[tier];
|
|
28
27
|
}
|
|
29
|
-
export function isZiggsOrchestrator(agentId) {
|
|
30
|
-
return ZIGGS_ORCHESTRATOR_IDS.has(agentId);
|
|
31
|
-
}
|
|
32
28
|
export function isFreeAllowlistedExecutor(executorId, description) {
|
|
33
29
|
if (!executorId)
|
|
34
30
|
return false;
|
|
@@ -82,14 +78,13 @@ export function applyFleetAgreementPricing(operation, payload, actingAgentId) {
|
|
|
82
78
|
}
|
|
83
79
|
const proposedTo = next.proposedTo != null ? String(next.proposedTo) : '';
|
|
84
80
|
const providerId = next.providerId != null ? String(next.providerId) : '';
|
|
85
|
-
//
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
// Tier C orchestrator proposing scope to a user (non-ziggs fleet orchestrators).
|
|
81
|
+
// A tier C orchestrator proposing scope to a user — 15 ZIG once at top.
|
|
82
|
+
//
|
|
83
|
+
// The ziggs delegate used to have its own branch above this one, keyed on a
|
|
84
|
+
// hardcoded id. It asked the same question with the same answer — that agent
|
|
85
|
+
// is tier C, so this line already priced it. A second way of asking the tier
|
|
86
|
+
// question the tier had already answered, which is the same shape that was
|
|
87
|
+
// removed from the backend copy.
|
|
93
88
|
const actingTier = resolveFleetTier(actingAgentId);
|
|
94
89
|
if (actingTier === 'C' && proposedTo && !isFirstPartyFleetAgent(proposedTo)) {
|
|
95
90
|
next.price = TIER_PRICE_CENTS.C;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { HistoryFormatter, AgreementFormatter } from '../formatters/index.js';
|
|
2
2
|
import { validateContext } from '../cognition/validateContext.js';
|
|
3
|
-
import { isBroadcastTarget, isOpaquePresentationRef } from '@ziggs-ai/api-client';
|
|
3
|
+
import { isBroadcastTarget, isOpaquePresentationRef, partySideIds } from '@ziggs-ai/api-client';
|
|
4
4
|
import { LANE_BOOK_KEY, allCollectedResults, allDelegatedAgreementIds, allPendingSubtasks, } from './taskBookkeeping.js';
|
|
5
5
|
/** Rough chars-per-token ratio for budgeting (English/JSON averages ~4). */
|
|
6
6
|
const CHARS_PER_TOKEN = 4;
|
|
@@ -191,12 +191,13 @@ ${this._renderDecisionSchemaFromActions(actions, senderMeta, ctxObj, omitMessage
|
|
|
191
191
|
const creatorIsYou = task.creatorIsYou;
|
|
192
192
|
const providerIsYou = task.providerIsYou;
|
|
193
193
|
if (ag?.agreementId) {
|
|
194
|
+
const named = (name) => partySideIds(parties[name]).join(' via ');
|
|
194
195
|
lines.push(`Agreement: ${ag.agreementId}${creatorIsYou ? ' (yours)' : ''}`);
|
|
195
|
-
lines.push(` Creator: ${
|
|
196
|
-
lines.push(` Provider: ${
|
|
196
|
+
lines.push(` Creator: ${named('creator') || 'N/A'}${creatorIsYou ? ' (You)' : ''}`);
|
|
197
|
+
lines.push(` Provider: ${named('provider') || 'N/A'}${providerIsYou ? ' (You)' : ''}`);
|
|
197
198
|
const proposal = ag.proposal;
|
|
198
199
|
if (proposal?.status) {
|
|
199
|
-
lines.push(` Proposal: ${proposal.status} (to ${
|
|
200
|
+
lines.push(` Proposal: ${proposal.status} (to ${named('proposedTo')}${task.proposedToIsYou ? ' - You' : ''})`);
|
|
200
201
|
}
|
|
201
202
|
const money = ag.money;
|
|
202
203
|
if (typeof money?.price === 'number' && money.price > 0) {
|
|
@@ -300,22 +301,19 @@ ${this._renderDecisionSchemaFromActions(actions, senderMeta, ctxObj, omitMessage
|
|
|
300
301
|
for (const ag of agreements || []) {
|
|
301
302
|
const agId = ag?.agreementId;
|
|
302
303
|
const parties = ag?.parties || {};
|
|
303
|
-
const
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
[
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
if (!agreementParties.has(pid))
|
|
317
|
-
agreementParties.set(pid, []);
|
|
318
|
-
agreementParties.get(pid).push({ agreementId: agId ?? '', role });
|
|
304
|
+
for (const role of ['creator', 'provider', 'payer', 'proposedTo']) {
|
|
305
|
+
// Both columns of a side are addressable and carry the same role: the
|
|
306
|
+
// principal is who the deal is with, the actor is who acts on it.
|
|
307
|
+
for (const pid of partySideIds(parties[role])) {
|
|
308
|
+
if (pid === myAgentId)
|
|
309
|
+
continue;
|
|
310
|
+
// Opaque presentation refs are not principal slots.
|
|
311
|
+
if (isOpaquePresentationRef(pid))
|
|
312
|
+
continue;
|
|
313
|
+
if (!agreementParties.has(pid))
|
|
314
|
+
agreementParties.set(pid, []);
|
|
315
|
+
agreementParties.get(pid).push({ agreementId: agId ?? '', role });
|
|
316
|
+
}
|
|
319
317
|
}
|
|
320
318
|
}
|
|
321
319
|
// Chat keeps the full directory — including opaque `rpb_*` / `psn_*` refs
|
|
@@ -380,7 +378,7 @@ ${this._renderDecisionSchemaFromActions(actions, senderMeta, ctxObj, omitMessage
|
|
|
380
378
|
lines.push('Set "action" to exactly one of the action names below.');
|
|
381
379
|
lines.push('Message text is rendered as markdown (CommonMark + GFM). You MAY use **bold**, *italic*, `code`, fenced code blocks, lists, links, and tables when they improve clarity — plain text is also fine.\n');
|
|
382
380
|
const replyTo = senderMeta.defaultReplyReceiverId || '<receiverId>';
|
|
383
|
-
const pendingProposals = (ctxObj.agreements || []).filter((a) => a.proposal?.status === 'pending' && (a.proposedToIsYou || isBroadcastTarget(a.parties?.proposedTo)));
|
|
381
|
+
const pendingProposals = (ctxObj.agreements || []).filter((a) => a.proposal?.status === 'pending' && (a.proposedToIsYou || isBroadcastTarget(a.parties?.proposedTo?.principal)));
|
|
384
382
|
if (pendingProposals.length > 0) {
|
|
385
383
|
lines.push(`PRIORITY: You have ${pendingProposals.length} pending proposal(s) directed at you. Respond BEFORE other actions.`);
|
|
386
384
|
lines.push(`{"thought": "...", "action": "<action_bound_to_agreement_respond>", "args": {"agreementId": "<id>", "action": "approve|reject"}}\n`);
|
|
@@ -92,7 +92,7 @@ function singleEventToOutcome(ev, ownAgentId) {
|
|
|
92
92
|
const parties = ag?.parties || {};
|
|
93
93
|
const state = result.state;
|
|
94
94
|
// Direct assignment to me (provider) — task spawned, citing an active agreement.
|
|
95
|
-
const isAssignedToMe = (result.providerIsYou || parties.provider === ownAgentId) &&
|
|
95
|
+
const isAssignedToMe = (result.providerIsYou || parties.provider?.actor === ownAgentId) &&
|
|
96
96
|
(state === 'active' || state === 'in-progress');
|
|
97
97
|
if (isAssignedToMe) {
|
|
98
98
|
return { kind: 'task-assigned', task };
|
|
@@ -421,7 +421,7 @@ export function applyOutcomeToCtx(ctx, outcome) {
|
|
|
421
421
|
const book = bookForDelegation(ctx);
|
|
422
422
|
if (tid && !(tid in book.pendingSubtasks)) {
|
|
423
423
|
book.pendingSubtasks[tid] = {
|
|
424
|
-
agentId: t.assigneeId ?? t.executorId ?? t.agreement?.parties?.provider ?? null,
|
|
424
|
+
agentId: t.assigneeId ?? t.executorId ?? t.agreement?.parties?.provider?.actor ?? null,
|
|
425
425
|
spawnedAt: Date.now(),
|
|
426
426
|
};
|
|
427
427
|
}
|
|
@@ -465,7 +465,7 @@ export function applyOutcomeToCtx(ctx, outcome) {
|
|
|
465
465
|
if (!existing) {
|
|
466
466
|
book.collectedResults.push({
|
|
467
467
|
taskId,
|
|
468
|
-
agentId: pending?.agentId ?? t?.assigneeId ?? t?.executorId ?? t?.agreement?.parties?.provider ?? null,
|
|
468
|
+
agentId: pending?.agentId ?? t?.assigneeId ?? t?.executorId ?? t?.agreement?.parties?.provider?.actor ?? null,
|
|
469
469
|
status: outcome.status,
|
|
470
470
|
result: payload,
|
|
471
471
|
});
|
|
@@ -479,7 +479,7 @@ export function applyOutcomeToCtx(ctx, outcome) {
|
|
|
479
479
|
existing.status = outcome.status;
|
|
480
480
|
existing.result = payload;
|
|
481
481
|
if (existing.agentId == null) {
|
|
482
|
-
existing.agentId = t?.assigneeId ?? t?.executorId ?? t?.agreement?.parties?.provider ?? null;
|
|
482
|
+
existing.agentId = t?.assigneeId ?? t?.executorId ?? t?.agreement?.parties?.provider?.actor ?? null;
|
|
483
483
|
}
|
|
484
484
|
}
|
|
485
485
|
if (agId) {
|
|
@@ -11,15 +11,28 @@ export declare function buildKickoffState(initial: string): ThinkingState;
|
|
|
11
11
|
export declare function buildClaimKickoffState(initial: string): ThinkingState;
|
|
12
12
|
/**
|
|
13
13
|
* Agreement-kickoff defaults. For every state whose transitions do not already
|
|
14
|
-
*
|
|
15
|
-
* state.
|
|
16
|
-
* (first match wins in AgentMachine._evaluateTransitions). Returns a NEW
|
|
17
|
-
* workflow — input states are not mutated.
|
|
14
|
+
* handle the corresponding probe, add a transition to the injected kickoff
|
|
15
|
+
* state. Returns a NEW workflow — input states are not mutated.
|
|
18
16
|
*
|
|
19
17
|
* Two kickoffs:
|
|
20
18
|
* - `kickingOff` — proposer-side approval → task_create
|
|
21
19
|
* - `claimKickingOff` — store-claim provider wake → chat_open + greet
|
|
22
20
|
* Direct-proposal counterparties (lifecycle approve, !proposedByMe, no
|
|
23
21
|
* fromClaimWake) still never auto-kickoff.
|
|
22
|
+
*
|
|
23
|
+
* **They are ordered differently on purpose** (first match wins in
|
|
24
|
+
* AgentMachine._evaluateTransitions):
|
|
25
|
+
*
|
|
26
|
+
* - `kickingOff` is appended LAST. It fires on an approval of a proposal THIS
|
|
27
|
+
* agent made, which the author was already expecting — whatever route they
|
|
28
|
+
* wrote for it should keep winning.
|
|
29
|
+
* - `claimKickingOff` is inserted FIRST. It fires on a wake the author never
|
|
30
|
+
* wrote a route for, and it has to beat the unconditional fallthrough an
|
|
31
|
+
* `idle` state uses to reach its listening loop — otherwise the claim is
|
|
32
|
+
* swallowed into the idle loop and the buyer is never greeted. Going first
|
|
33
|
+
* is safe because its `when` is narrow: only a `fromClaimWake` approve
|
|
34
|
+
* matches, so nothing else is shadowed. An author who wants the claim for
|
|
35
|
+
* themselves keys on `fromClaimWake`, which suppresses the injection
|
|
36
|
+
* outright (stateHandlesClaimKickoff).
|
|
24
37
|
*/
|
|
25
38
|
export declare function injectKickoffDefault(workflow: Workflow): Workflow;
|