@agrentingai/paperclip-adapter 0.2.2 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +55 -1
- package/dist/server/index.cjs +97 -6
- package/dist/server/index.cjs.map +1 -1
- package/dist/server/index.d.cts +73 -2
- package/dist/server/index.d.ts +73 -2
- package/dist/server/index.js +85 -6
- package/dist/server/index.js.map +1 -1
- package/dist/ui/index.cjs +1 -1
- package/dist/ui/index.cjs.map +1 -1
- package/dist/ui/index.js +1 -1
- package/dist/ui/index.js.map +1 -1
- package/package.json +9 -3
- package/server/src/adapter.ts +145 -1
- package/server/src/index.ts +16 -0
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agrentingai/paperclip-adapter",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "Paperclip adapter for Agrenting — remote AI agent orchestration via the Agrenting platform",
|
|
3
|
+
"version": "0.3.0",
|
|
4
|
+
"description": "Paperclip adapter for Agrenting — remote AI agent orchestration via the Agrenting platform. Implements the canonical Paperclip AgentAdapter contract for plugin loading via ~/.paperclip/adapter-plugins.json.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"exports": {
|
|
7
7
|
"./server": {
|
|
@@ -30,9 +30,11 @@
|
|
|
30
30
|
},
|
|
31
31
|
"keywords": [
|
|
32
32
|
"paperclip",
|
|
33
|
+
"paperclipai",
|
|
33
34
|
"agrenting",
|
|
34
35
|
"adapter",
|
|
35
|
-
"ai-agents"
|
|
36
|
+
"ai-agents",
|
|
37
|
+
"agent-adapter"
|
|
36
38
|
],
|
|
37
39
|
"author": "AgRenting",
|
|
38
40
|
"license": "MIT",
|
|
@@ -40,6 +42,10 @@
|
|
|
40
42
|
"type": "git",
|
|
41
43
|
"url": "git+https://github.com/AgRenting/paperclip-adapter.git"
|
|
42
44
|
},
|
|
45
|
+
"bugs": {
|
|
46
|
+
"url": "https://github.com/AgRenting/paperclip-adapter/issues"
|
|
47
|
+
},
|
|
48
|
+
"homepage": "https://agrenting.com/docs/platform/paperclip-adapter",
|
|
43
49
|
"engines": {
|
|
44
50
|
"node": ">=20.0.0"
|
|
45
51
|
},
|
package/server/src/adapter.ts
CHANGED
|
@@ -1003,9 +1003,145 @@ export function processIncomingMessage(
|
|
|
1003
1003
|
return formatAgentResponse(senderName, message.content);
|
|
1004
1004
|
}
|
|
1005
1005
|
|
|
1006
|
+
// ─── Canonical Paperclip adapter contract ──────────────────────────────────
|
|
1007
|
+
// Matches the canonical adapter shape Paperclip expects per
|
|
1008
|
+
// `paperclipai/paperclip/doc/SPEC-implementation.md` and the reference
|
|
1009
|
+
// `NousResearch/hermes-paperclip-adapter`. These named exports let the
|
|
1010
|
+
// package load via `~/.paperclip/adapter-plugins.json`.
|
|
1011
|
+
|
|
1012
|
+
/** Paperclip skill shape (subset of the canonical Paperclip Skill). */
|
|
1013
|
+
export interface PaperclipSkill {
|
|
1014
|
+
id: string;
|
|
1015
|
+
name: string;
|
|
1016
|
+
description?: string;
|
|
1017
|
+
}
|
|
1018
|
+
|
|
1019
|
+
/**
|
|
1020
|
+
* Detect a sensible default model/provider for the configured Agrenting agent.
|
|
1021
|
+
* Paperclip calls this to pre-populate the adapter UI when an agent is
|
|
1022
|
+
* created. Returns null if no info is available.
|
|
1023
|
+
*/
|
|
1024
|
+
export async function detectModel(
|
|
1025
|
+
config: Pick<AgrentingAdapterConfig, "agrentingUrl" | "apiKey" | "agentDid">
|
|
1026
|
+
): Promise<{ provider: string; model: string } | null> {
|
|
1027
|
+
if (!config.agentDid) return null;
|
|
1028
|
+
try {
|
|
1029
|
+
const profile = await getAgentProfile(config as AgrentingAdapterConfig, config.agentDid);
|
|
1030
|
+
const provider = (profile as { ai_provider?: string }).ai_provider ?? null;
|
|
1031
|
+
const model = (profile as { ai_model?: string }).ai_model ?? null;
|
|
1032
|
+
if (provider && model) return { provider, model };
|
|
1033
|
+
} catch {
|
|
1034
|
+
// Surface as "no detection" rather than a hard error — Paperclip falls
|
|
1035
|
+
// back to user input.
|
|
1036
|
+
}
|
|
1037
|
+
return null;
|
|
1038
|
+
}
|
|
1039
|
+
|
|
1040
|
+
/**
|
|
1041
|
+
* Enumerate the configured Agrenting agent's capabilities and map them to
|
|
1042
|
+
* Paperclip's Skill shape.
|
|
1043
|
+
*/
|
|
1044
|
+
export async function listSkills(
|
|
1045
|
+
config: AgrentingAdapterConfig
|
|
1046
|
+
): Promise<PaperclipSkill[]> {
|
|
1047
|
+
const profile = await getAgentProfile(config, config.agentDid);
|
|
1048
|
+
const capabilities = profile.capabilities ?? [];
|
|
1049
|
+
return capabilities.map((cap) => ({
|
|
1050
|
+
id: `${config.agentDid}:${cap}`,
|
|
1051
|
+
name: cap,
|
|
1052
|
+
description: `Capability "${cap}" of agent ${config.agentDid}`,
|
|
1053
|
+
}));
|
|
1054
|
+
}
|
|
1055
|
+
|
|
1056
|
+
/**
|
|
1057
|
+
* Reconcile the agent's current capabilities against Paperclip's local skill
|
|
1058
|
+
* registry. Returns sets to add and remove.
|
|
1059
|
+
*/
|
|
1060
|
+
export async function syncSkills(
|
|
1061
|
+
config: AgrentingAdapterConfig,
|
|
1062
|
+
existing: PaperclipSkill[]
|
|
1063
|
+
): Promise<{ added: PaperclipSkill[]; removed: PaperclipSkill[] }> {
|
|
1064
|
+
const remote = await listSkills(config);
|
|
1065
|
+
const remoteIds = new Set(remote.map((s) => s.id));
|
|
1066
|
+
const existingIds = new Set(existing.map((s) => s.id));
|
|
1067
|
+
return {
|
|
1068
|
+
added: remote.filter((s) => !existingIds.has(s.id)),
|
|
1069
|
+
removed: existing.filter((s) => !remoteIds.has(s.id)),
|
|
1070
|
+
};
|
|
1071
|
+
}
|
|
1072
|
+
|
|
1073
|
+
/**
|
|
1074
|
+
* Session codec — Paperclip uses this to serialise session state across
|
|
1075
|
+
* heartbeats. Hirings carry no rich session state, so we pass JSON through.
|
|
1076
|
+
*/
|
|
1077
|
+
export const sessionCodec = {
|
|
1078
|
+
encode(state: unknown): string {
|
|
1079
|
+
return JSON.stringify(state ?? null);
|
|
1080
|
+
},
|
|
1081
|
+
decode(blob: string | null | undefined): unknown {
|
|
1082
|
+
if (!blob) return null;
|
|
1083
|
+
try {
|
|
1084
|
+
return JSON.parse(blob);
|
|
1085
|
+
} catch {
|
|
1086
|
+
return null;
|
|
1087
|
+
}
|
|
1088
|
+
},
|
|
1089
|
+
};
|
|
1090
|
+
|
|
1091
|
+
/**
|
|
1092
|
+
* Canonical `AgentAdapter.invoke`. Forwards to {@link execute}.
|
|
1093
|
+
*/
|
|
1094
|
+
export async function invoke(
|
|
1095
|
+
config: AgrentingAdapterConfig,
|
|
1096
|
+
params: {
|
|
1097
|
+
input: string;
|
|
1098
|
+
capability: string;
|
|
1099
|
+
instructions?: string;
|
|
1100
|
+
maxPrice?: string;
|
|
1101
|
+
paymentType?: string;
|
|
1102
|
+
}
|
|
1103
|
+
): Promise<AgrentingExecutionResult> {
|
|
1104
|
+
return execute(config, params);
|
|
1105
|
+
}
|
|
1106
|
+
|
|
1107
|
+
/**
|
|
1108
|
+
* Canonical `AgentAdapter.status`. Returns the current run status.
|
|
1109
|
+
*/
|
|
1110
|
+
export async function status(
|
|
1111
|
+
config: AgrentingAdapterConfig,
|
|
1112
|
+
taskId: string
|
|
1113
|
+
): Promise<{
|
|
1114
|
+
status: AgrentingTaskStatus;
|
|
1115
|
+
progressPercent: number;
|
|
1116
|
+
progressMessage?: string;
|
|
1117
|
+
}> {
|
|
1118
|
+
const progress = await getTaskProgress(config, taskId);
|
|
1119
|
+
return {
|
|
1120
|
+
status: progress.status,
|
|
1121
|
+
progressPercent: progress.progressPercent,
|
|
1122
|
+
progressMessage: progress.progressMessage,
|
|
1123
|
+
};
|
|
1124
|
+
}
|
|
1125
|
+
|
|
1126
|
+
/**
|
|
1127
|
+
* Canonical `AgentAdapter.cancel`. Cancels a running task; throws on failure
|
|
1128
|
+
* so Paperclip can treat the call as a void Promise.
|
|
1129
|
+
*/
|
|
1130
|
+
export async function cancel(
|
|
1131
|
+
config: AgrentingAdapterConfig,
|
|
1132
|
+
taskId: string
|
|
1133
|
+
): Promise<void> {
|
|
1134
|
+
const result = await cancelTask(config, taskId);
|
|
1135
|
+
if (!result.success) {
|
|
1136
|
+
throw new Error(result.error ?? "Failed to cancel task");
|
|
1137
|
+
}
|
|
1138
|
+
}
|
|
1139
|
+
|
|
1006
1140
|
/**
|
|
1007
1141
|
* Create the server-side adapter module.
|
|
1008
|
-
*
|
|
1142
|
+
* Backward-compat convenience for callers that prefer a single bundle. New
|
|
1143
|
+
* Paperclip plugin loaders should use the named exports directly via
|
|
1144
|
+
* `~/.paperclip/adapter-plugins.json`.
|
|
1009
1145
|
*/
|
|
1010
1146
|
export function createServerAdapter() {
|
|
1011
1147
|
return {
|
|
@@ -1040,5 +1176,13 @@ export function createServerAdapter() {
|
|
|
1040
1176
|
getTransactions,
|
|
1041
1177
|
deposit,
|
|
1042
1178
|
withdraw,
|
|
1179
|
+
// Canonical contract additions:
|
|
1180
|
+
invoke,
|
|
1181
|
+
status,
|
|
1182
|
+
cancel,
|
|
1183
|
+
detectModel,
|
|
1184
|
+
listSkills,
|
|
1185
|
+
syncSkills,
|
|
1186
|
+
sessionCodec,
|
|
1043
1187
|
};
|
|
1044
1188
|
}
|
package/server/src/index.ts
CHANGED
|
@@ -42,7 +42,23 @@ export {
|
|
|
42
42
|
listHirings,
|
|
43
43
|
autoSelectAgent,
|
|
44
44
|
executeWithRetry,
|
|
45
|
+
// Canonical Paperclip AgentAdapter contract (for `~/.paperclip/adapter-plugins.json`).
|
|
46
|
+
// See `paperclipai/paperclip/doc/SPEC-implementation.md` and the reference
|
|
47
|
+
// `NousResearch/hermes-paperclip-adapter`.
|
|
48
|
+
execute,
|
|
49
|
+
testEnvironment,
|
|
50
|
+
getConfigSchema,
|
|
51
|
+
cancelTask,
|
|
52
|
+
getTaskProgress,
|
|
53
|
+
invoke,
|
|
54
|
+
status,
|
|
55
|
+
cancel,
|
|
56
|
+
detectModel,
|
|
57
|
+
listSkills,
|
|
58
|
+
syncSkills,
|
|
59
|
+
sessionCodec,
|
|
45
60
|
} from "./adapter.js";
|
|
61
|
+
export type { PaperclipSkill } from "./adapter.js";
|
|
46
62
|
export type {
|
|
47
63
|
AgrentingAdapterConfig,
|
|
48
64
|
AgrentingExecutionResult,
|